# packages

pkgId: 5fa4399d9327771f3fe7636cc141602c4c2fd2e5824d4a73c80f508d69e4bb56
name: python-brianmechanisms
arch: src
version: 0.1.30
epoch: 0
release: 1
summary: Python module for designing mechanisms and robots
url: https://github.com/brianmechanisms/brianmechanisms-designer
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brianmechanisms-0.1.30-1.src.rpm
checksum_type: sha256
description:
  Brian Mechanisms is a Python module designed for engineers and developers to easily design and simulate various mechanical mechanisms and robots. It provides a collection of tools and algorithms for kinematic analysis, motion planning, and visualization of mechanical systems.


  - Kinematic analysis for various types of mechanisms, including linkages, gears, and robotic arms.
  - Motion planning algorithms for path generation and trajectory optimization.
  - Visualization tools to create interactive plots and animations of mechanical systems.
  - Integration with popular libraries such as NumPy and Matplotlib for scientific computing and visualization.


  ou can install Brian Mechanisms using pip:

  ```bash
  Copy code
  pip install brianmechanisms
  ```



  The `Locii` class is used for plotting and/or animating output paths of rigid link mechanisms with a `θ` input. Each link has a number of `points` whose lengths are given relative to the pivot point for that mechanism. The pivot point has its length set to `0`.


  Each link is defined by a dictionary containing the following keys:

  - `points`: A dictionary defining the points on the link and their respective lengths.
  - `speed`: The speed of the link (optional).
  - `equation`: A string representing the equation for the displacement of the link.
  - `origin`: The origin point of the link.
  - `len_factor`: A length factor for scaling the link (optional).
  - `speed_factor`: A factor for scaling the speed of the link (optional).
  - `speed_source`: The source of the speed, referencing another link's speed (optional).
  - `theta0`: The initial angle for the link (optional).
  - `output`: The output point of the link (optional).

  Example of defining links:

  ```python
  link1 = {
      "points": {
           "O": 0, "A": 1
      },
      "speed": 1,
      "equation": "np.cos(x), np.sin(x)",
      "origin": "{0,0}"
  }

  link2 = {
      "points": {
          "A": 0, "B": 1
      },
      "len_factor": 1,
      "speed_factor": 2,
      "speed_source": "link1.speed",
      "equation": "np.cos(speed_factor * speed_source * x), np.sin(speed_factor * speed_source * x)",
      "origin": "link1.A",
      "theta0": 1,
      "output": "B"
  }
  ```



  By default, the function will plot the loci of all the given points of the mechanism using dashed lines. The output is plotted using a solid line, specified by the output property in the link's settings.


  To draw the mechanism in addition to the loci, define the mechanism_theta property. The mechanism will be drawn at `0 = mechanism_theta`.




  This example demonstrates how to define links and use the `Locii` class to plot and animate the Tusi Couple mechanism.

  ```python
  from brianmechanisms import Locii
  import matplotlib.pyplot as plt
  from matplotlib.animation import FuncAnimation
  import numpy as np

  link1 = {
      "points": {
           "O": 0, "A": 1
      },
      "speed": 1,
      "equation": "np.cos(x), np.sin(x)",
      "origin": "{0,0}"
  }

  link2 = {
      "points": {
          "A": 0, "B": 1
      },
      "len_factor": 1,
      "speed_factor": 1,
      "speed_source": "link1.speed",
      "equation": "np.cos(speed_factor * speed_source * x), np.sin(speed_factor * speed_source * x)",
      "origin": "link1.A",
      "theta0": 1,
      "output": "B"
  }

  linksTemplate = {
      "link1": link1.copy(),
      "link2": link2.copy()
  }

  fig, axs = plt.subplots(1, 1)
  locii = Locii(linksTemplate, {})
  fig, ax = locii.plotOutPutPaths(title={"title": "Tusi Couple", "sub": "Subtitle Example"}, plotConfig={"ax": axs, "fig": fig, "legend": False, "axes": False, "mechanism_theta": 45, "ani": True})

  ani3 = FuncAnimation(fig, locii.update, frames=np.arange(0, 360, 10), fargs=(ax, {"title": "Example Plot", "sub": "Subtitle Example"}, {"ax": axs, "fig": fig, "legend": False, "axes": False, "mechanism_theta": 45, "ani": True}), interval=100)

  plt.show()

  HTML(ani3.to_jshtml())
  ```


  To animate the plot and save it as a video file (e.g., MP4), use the FuncAnimation class from matplotlib.animation and specify the writer (e.g., FFMpegWriter):

  ```python
  from matplotlib.animation import FFMpegWriter

  writer = FFMpegWriter(fps=10, metadata={'title': 'Tusi Couple', 'artist': 'brianmechanisms', 'comment': 'Tusi Couple Animation'})
  ani3.save('tusicouple.mp4', writer=writer)
  ```

  This documentation provides a basic overview of how to use the brianmechanisms module, specifically focusing on the Locii class for plotting and animating rigid link mechanisms. For more detailed information and additional features, refer to the official documentation and examples provided in the module.


  The `plotConfig` dictionary allows you to customize various aspects of your plot and animation. Here are the key settings you can use:

  -`ax`: Specifies the Matplotlib axes object to use for plotting. If not provided, a new axes object will be created.
  - `fig`: Specifies the Matplotlib figure object to use for the plot. This allows you to add the plot to an existing figure.
  - `legend`: A boolean flag that controls whether a legend should be displayed on the plot. If set to False, no legend will be shown.
  - `axes`: A boolean flag that controls whether the axes should be displayed on the plot. If set to False, the axes will be hidden.
  - `mechanism_theta`: Specifies the angle (in degrees) at which the mechanism should be drawn. This setting allows you to visualize the mechanism at a specific angle.
  - `ani`: A boolean flag that indicates whether the plot should be animated. If set to True, the animation will be enabled.




  ![Tusi Couple](examples/TusiCouple.gif)

  ![Tusi Couple](examples/TusiCouple1.gif)

  ![Hypocycloids](examples/hypocycloids.png)

  ![Hypoctrochoids](examples/hypotrochoids.png)

  ![Epictrochoids](examples/epitrochoids.png)


pkgId: 90ef7006ca90952d001c21cb1ea768f26f7089f5e299200b8a547e07cdf040cc
name: python-brickflows
arch: src
version: 1.2.0
epoch: 0
release: 1
summary: Deploy scalable workflows to databricks using python
url: https://github.com/Nike-Inc/brickflow
rpm_license: Apache-2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brickflows-1.2.0-1.src.rpm
checksum_type: sha256
description:
  Thanks to all the [contributors](https://github.com/Nike-Inc/brickflow/blob/main/CONTRIBUTORS.md) who have helped ideate, develop and bring Brickflow to its current state.

  We're delighted that you're interested in contributing to our project! To get started,
  please carefully read and follow the guidelines provided in our [contributing](https://github.com/Nike-Inc/brickflow/blob/main/CONTRIBUTING.md) document.

  Brickflow documentation can be found [here](https://engineering.nike.com/brickflow/).


  1. Install brickflows
  ```shell
  pip install brickflows
  ```
  2. Install [Databricks CLI](https://docs.databricks.com/en/dev-tools/cli/databricks-cli.html)
  ```shell
  curl -fsSL https://raw.githubusercontent.com/databricks/setup-cli/main/install.sh | sudo sh
  ```
  3. Configure Databricks cli with workspace token. This configures your `~/.databrickscfg` file.
  ```shell
  databricks configure --token
  ```

  1. Create your first workflow using brickflow
  ```shell
  mkdir hello-world-brickflow
  cd hello-world-brickflow
  brickflow projects add
  ```
  2. Provide the following inputs
  ```shell
  Project name: hello-world-brickflow
  Path from repo root to project root (optional) [.]: .
  Path from project root to workflows dir: workflows
  Git https url: https://github.com/Nike-Inc/brickflow.git
  Brickflow version [auto]:<hit enter>
  Spark expectations version [0.5.0]: 0.8.0
  Skip entrypoint [y/N]: N
  ```
  _Note: You can provide your own github repo url._
  3. Create a new file hello_world_wf.py in the workflows directory
  ```shell
  touch workflows/hello_world_wf.py
  ```
  4. Copy the following code in hello_world_wf.py file
  ```python
  from brickflow import (
      ctx,
      Cluster,
      Workflow,
      NotebookTask,
  )
  from airflow.operators.bash import BashOperator
  cluster = Cluster(
      name="job_cluster",
      node_type_id="m6gd.xlarge",
      spark_version="13.3.x-scala2.12",
      min_workers=1,
      max_workers=2,
  )
  wf = Workflow(
      "hello_world_workflow",
      default_cluster=cluster,
      tags={
          "product_id": "brickflow_demo",
      },
      common_task_parameters={
          "catalog": "<uc-catalog-name>",
          "database": "<uc-schema-name>",
      },
  )
  @wf.task

  def start():
      print(f"Environment: {ctx.env}")
  @wf.notebook_task

  def example_notebook():
      return NotebookTask(
          notebook_path="notebooks/example_notebook.py",
          base_parameters={
              "some_parameter": "some_value",  # in the notebook access these via dbutils.widgets.get("some_parameter")
          },
      )
  @wf.task(depends_on=[start, example_notebook])

  def list_lending_club_data_files():
      return BashOperator(
          task_id=list_lending_club_data_files.__name__,
          bash_command="ls -lrt /dbfs/databricks-datasets/samples/lending_club/parquet/",
      )
  @wf.task(depends_on=list_lending_club_data_files)

  def lending_data_ingest():
      ctx.spark.sql(
          f"""
          CREATE TABLE IF NOT EXISTS
          {ctx.dbutils_widget_get_or_else(key="catalog", debug="development")}.\
          {ctx.dbutils_widget_get_or_else(key="database", debug="dummy_database")}.\
          {ctx.dbutils_widget_get_or_else(key="brickflow_env", debug="local")}_lending_data_ingest
          USING DELTA -- this is default just for explicit purpose
          SELECT * FROM parquet.`dbfs:/databricks-datasets/samples/lending_club/parquet/`
      """
      )
  ```
  _Note: Modify the values of catalog/database for common_task_parameters._
  5. Create a new file example_notebook.py in the notebooks directory
  ```shell
  mkdir notebooks
  touch notebooks/example_notebook.py
  ```
  6. Copy the following code in the example_notebook.py file
  ```python

  print("hello world")
  ```

  ```shell
  brickflow projects deploy --project hello-world-brickflow -e local
  ```

  1. Login to databricks workspace
  2. Go to the workflows and select the workflow
  <p align="center">
  <img src=https://raw.githubusercontent.com/Nike-Inc/brickflow/master/docs/img/workflow.png?raw=true width=1000></p>
  4. click on the run button

  Refer to the [examples](https://github.com/Nike-Inc/brickflow/tree/main/examples/brickflow_examples) for more examples.


pkgId: 1dd1cdeb30087f4556c2bf5be3347fefaf222b7d90ac86c3017fac35f7679971
name: python-brickllm
arch: src
version: 1.1.2
epoch: 0
release: 1
summary: Library for generating RDF files following BrickSchema ontology using LLM
url: https://brickllm.com/
rpm_license: BSD-3-Clause
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brickllm-1.1.2-1.src.rpm
checksum_type: sha256
description:
  <p align="center">
    <img src="https://raw.githubusercontent.com/EURAC-EEBgroup/brick-llm/refs/heads/main/docs/assets/brickllm_banner.png" alt="BrickLLM" style="width: 100%;">
  </p>



  BrickLLM is a Python library for generating RDF files following the BrickSchema ontology using Large Language Models (LLMs).



  - Generate BrickSchema-compliant RDF files from natural language descriptions of buildings and facilities
  - Support for multiple LLM providers (OpenAI, Anthropic, Fireworks)
  - Customizable graph execution with LangGraph
  - Easy-to-use API for integrating with existing projects



  You can install BrickLLM using pip:

  ``` bash
  pip install brickllm
  ```

  <details>
  <summary><b>Development Installation</b></summary>

  [Poetry](https://python-poetry.org/) is used for dependency management during development. To install BrickLLM for contributing, follow these steps:

  ``` bash

  git clone https://github.com/EURAC-EEBgroup/brickllm-lib.git
  cd brick-llm


  python -m venv .venv


  source .venv/bin/activate # Linux/Mac
  .venv\Scripts\activate # Windows


  pip install poetry
  poetry install


  pre-commit install
  ```

  </details>



  Here's a simple example of how to use BrickLLM:

  ``` python
  from brickllm.graphs import BrickSchemaGraph

  building_description = """
  I have a building located in Bolzano.
  It has 3 floors and each floor has 1 office.
  There are 2 rooms in each office and each room has three sensors:
  - Temperature sensor;
  - Humidity sensor;
  - CO sensor.
  """


  brick_graph = BrickSchemaGraph(model="openai")


  brick_graph.display()


  input_data = {
      "user_prompt": building_description
  }


  result = brick_graph.run(input_data=input_data, stream=False)


  print(result)


  brick_graph.save_ttl_output("my_building.ttl")
  ```

  <details>
  <summary><b>Using Custom LLM Models</b></summary>

  BrickLLM supports using custom LLM models. Here's an example using OpenAI's GPT-4o:

  ``` python
  from brickllm.graphs import BrickSchemaGraph
  from langchain_openai import ChatOpenAI

  custom_model = ChatOpenAI(temperature=0, model="gpt-4o")
  brick_graph = BrickSchemaGraph(model=custom_model)


  input_data = {
      "user_prompt": building_description
  }


  result = brick_graph.run(input_data=input_data, stream=False)
  ```
  </details>

  <details>
  <summary><b>Using Local LLM Models</b></summary>
  <p>BrickLLM supports using local LLM models employing the <a href="https://ollama.com/">Ollama framework</a>. Currently, only our finetuned model is supported.</p>



  You can easily set up and run the Ollama environment using Docker Compose. The finetuned model file will be automatically downloaded inside the container. Follow these steps:

  1. Clone the repository and navigate to the `finetuned` directory containing the `Dockerfile` and `docker-compose.yml`.
  2. Run the following command to build and start the container:
      ```bash
      docker-compose up --build -d
      ```
  3. Verify that the docker is running on localhost:11434:
     ```bash
     docker ps
     ```
     if result is:
     ```
     CONTAINER ID   IMAGE                         COMMAND                  CREATED          STATUS          PORTS                     NAMES
     1e9bff7c2f7b   finetuned-ollama-llm:latest   "/entrypoint.sh"         42 minutes ago   Up 42 minutes   11434/tcp                 compassionate_wing
     ```

     so run the docker image specifying the port:
     ```bash
     docker run -d -p 11434:11434 finetuned-ollama-llm:latest
     docker ps
     ```

     the result will be like:
     ```
     CONTAINER ID   IMAGE                         COMMAND                  CREATED         STATUS          PORTS                      NAMES
     df8b31d4ed86   finetuned-ollama-llm:latest   "/entrypoint.sh"         7 seconds ago   Up 7 seconds    0.0.0.0:11434->11434/tcp   eloquent_jennings
     ```
     check if ollama is runnin in the port 11434:
     ```
     curl http://localhost:11434
     ```
     Result should be:
     ```
     Ollama is running
     ```
  This will download the model file, create the model in Ollama, and serve it on port `11434`. The necessary directories will be created automatically.



  If you prefer to set up the model manually, follow these steps:

  1. Download the `.gguf` file from <a href="https://huggingface.co/Giudice7/llama31-8B-brick-v8/tree/main">here</a>.
  2. Create a file named `Modelfile` with the following content:
      ```bash
      FROM ./unsloth.Q4_K_M.gguf
      ```

  3. Place the downloaded `.gguf` file in the same folder as the `Modelfile`.
  4. Ensure Ollama is running on your system.
  5. Run the following command to create the model in Ollama:
      ```bash
      ollama create llama3.1:8b-brick-v8 -f Modelfile
      ```

  Once you've set up the model in Ollama, you can use it in your code as follows:

  ``` python
  from brickllm.graphs import BrickSchemaGraphLocal

  instructions = """
  Your job is to generate a RDF graph in Turtle format from a description of energy systems and sensors of a building in the following input, using the Brick ontology.

  - Each subject, object of predicate must start with a @prefix.
  - Use the prefix bldg: with IRI <http://my-bldg#> for any created entities.
  - Use the prefix brick: with IRI <https://brickschema.org/schema/Brick#> for any Brick entities and relationships used.
  - Use the prefix unit: with IRI <http://qudt.org/vocab/unit/> and its ontology for any unit of measure defined.
  - When encoding the timeseries ID of the sensor, you must use the following format: ref:hasExternalReference [ a ref:TimeseriesReference ; ref:hasTimeseriesId 'timeseriesID' ].
  - When encoding identifiers or external references, such as building/entities IDs, use the following schema: ref:hasExternalReference [ a ref:ExternalReference ; ref:hasExternalReference ‘id/reference’ ].
  - When encoding numerical reference, use the schema [brick:value 'value' ; \n brick:hasUnit unit:'unit' ] .
  -When encoding coordinates, use the schema brick:coordinates [brick:latitude "lat" ; brick:longitude "long" ].
  The response must be the RDF graph that includes all the @prefix of the ontologies used in the triples. The RDF graph must be created in Turtle format. Do not add any other text or comment to the response.
  """

  building_description = """
  The building (external ref: 'OB103'), with coordinates 33.9614, -118.3531, has a total area of 500 m². It has three zones, each with its own air temperature sensor.
  The building has an electrical meter that monitors data of a power sensor. An HVAC equipment serves all three zones and its power usage is measured by a power sensor.

  Timeseries IDs and unit of measure of the sensors:
  - Building power consumption: '1b3e-29dk-8js7-f54v' in watts.
  - HVAC power consumption: '29dh-8ks3-fvjs-d92e' in watts.
  - Temperature sensor zone 1: 't29s-jk83-kv82-93fs' in celsius.
  - Temperature sensor zone 2: 'f29g-js92-df73-l923' in celsius.
  - Temperature sensor zone 3: 'm93d-ljs9-83ks-29dh' in celsius.
  """


  brick_graph_local = BrickSchemaGraphLocal(model="llama3.1:8b-brick")


  brick_graph_local.display()


  input_data = {
      "user_prompt": building_description,
      "instructions": instructions
  }


  result = brick_graph_local.run(input_data=input_data, stream=False)


  print(result)


  brick_graph_local.save_ttl_output("my_building_local.ttl")
  ```
  </details>



  For more detailed information on how to use BrickLLM, please refer to our [documentation](https://brickllm.com/docs).



  We welcome contributions to BrickLLM! Please see our [contributing guidelines](CONTRIBUTING.md) for more information.



  BrickLLM is released under the BSD-3-Clause License. See the [LICENSE](LICENSE) file for details.



  For any questions or support, please contact:

  - Marco Perini <marco.perini@eurac.edu>
  - Daniele Antonucci <daniele.antonucci@eurac.edu>
  - Rocco Giudice <rocco.giudice@polito.it>



  Please cite us if you use the library

  [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.14039358.svg)](https://zenodo.org/doi/10.5281/zenodo.14039358)



  BrickLLM is developed and maintained by the Energy Efficiency in Buildings group at EURAC Research. Thanks to the contribution of:
  - Moderate project: Horizon Europe research and innovation programme under grant agreement No 101069834
  - Politecnico of Turin, in particular to @Rocco Giudice for his work in developing model generation using local language model


pkgId: 3f6732d96c9ab6134ddb817df5475dcaec572a2490c31fb8dd575cbb3de40e55
name: python-brickschema
arch: src
version: 0.7.5
epoch: 0
release: 1
summary: A library for working with the Brick ontology for buildings (brickschema.org)
url: https://brickschema.org
rpm_license: BSD-3-Clause
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brickschema-0.7.5-1.src.rpm
checksum_type: sha256
description:
  ![Build](https://github.com/BrickSchema/py-brickschema/workflows/Build/badge.svg)
  [![Documentation Status](https://readthedocs.org/projects/brickschema/badge/?version=latest)](https://brickschema.readthedocs.io/en/latest/?badge=latest)
  [![PyPI version](https://badge.fury.io/py/brickschema.svg)](https://badge.fury.io/py/brickschema)

  Documentation available at [readthedocs](https://brickschema.readthedocs.io/en/latest/)



  The `brickschema` package requires Python >= 3.8. It can be installed with `pip`:

  ```
  pip install brickschema
  ```

  The `brickschema` package offers several installation configuration options for reasoning.
  The default bundled [OWLRL](https://pypi.org/project/owlrl/) reasoner delivers correct results, but exhibits poor performance on large or complex ontologies (we have observed minutes to hours) due to its bruteforce implementation.

  The [Allegro reasoner](https://franz.com/agraph/support/documentation/current/materializer.html) has better performance and implements enough of the OWLRL profile to be useful. We execute Allegrograph in a Docker container, which requires the `docker` package. To install support for the Allegrograph reasoner, use

  ```
  pip install brickschema[allegro]
  ```

  The [reasonable Reasoner](https://github.com/gtfierro/reasonable) offers even better performance than the Allegro reasoner, but is currently only packaged for Linux and MacOS platforms. To install support for the reasonable Reasoner, use

  ```
  pip install brickschema[reasonable]
  ```



  The main `Graph` object is just a subclass of the excellent [RDFlib Graph](https://rdflib.readthedocs.io/en/stable/) library, so all features on `rdflib.Graph` will also work here.

  Brief overview of the main features of the `brickschema` package:

  ```python
  import brickschema



  g = brickschema.Graph(load_brick=True)






  g.load_file("mbuilding.ttl")

  g.parse("https://brickschema.org/ttl/soda_brick.ttl", format="ttl")


  g.expand(profile="owlrl")
  g.expand(profile="shacl") # infers Brick classes from Brick tags


  valid, _, resultsText = g.validate()
  if not valid:
      print("Graph is not valid!")
      print(resultsText)


  res = g.query("""SELECT ?afs ?afsp ?vav WHERE  {
      ?afs    a       brick:Air_Flow_Sensor .
      ?afsp   a       brick:Air_Flow_Setpoint .
      ?afs    brick:isPointOf ?vav .
      ?afsp   brick:isPointOf ?vav .
      ?vav    a   brick:VAV
  }""")
  for row in res:
      print(row)



  g.serve("localhost:8080")

  ```



  `brickschema` supports a number of optional features:

  - `[all]`: Install all features below
  - `[brickify]`: install `brickify` tool for converting metadata from existing sources
  - `[web]`: allow serving of Brick models over HTTP + web interface
  - `[merge]`: initial support for merging Brick models with different identifiers together
  - `[persistence]`: support for saving and loading Brick models to/from disk
  - `[allegro]`: use Allegrograph reasoner
  - `[reasonable]`: use Reasonable reasoner



  `brickschema` makes it easier to employ reasoning on your graphs. Simply call the `expand` method on the Graph object with one of the following profiles:
  - `"rdfs"`: RDFS reasoning
  - `"owlrl"`: OWL-RL reasoning (using 1 of 3 implementations below)
  - `"vbis"`: add VBIS tags to Brick entities
  - `"shacl"`: infer Brick classes from Brick tags, among other things


  ```python
  from brickschema import Graph

  g = Graph(load_brick=True)
  g.load_file("test.ttl")
  g.expand(profile="owlrl")
  print(f"Inferred graph has {len(g)} triples")
  ```


  The package will automatically use the fastest available reasoning implementation for your system:

  - `reasonable` (fastest, Linux-only for now): `pip install brickschema[reasonable]`
  - `Allegro` (next-fastest, requires Docker): `pip install brickschema[allegro]`
  - OWLRL (default, native Python implementation): `pip install brickschema`

  To use a specific reasoner, specify `"reasonable"`, `"allegrograph"` or `"owlrl"` as the value for the `backend` argument to `graph.expand`.



  `brickschema` can produce a Brick model from a JSON export of a Haystack model.
  Then you can use this package as follows:

  ```python
  import json
  from brickschema import Graph
  model = json.load(open("haystack-export.json"))
  g = Graph(load_brick=True).from_haystack("http://project-haystack.org/carytown#", model)
  points = g.query("""SELECT ?point ?type WHERE {
      ?point rdf:type/rdfs:subClassOf* brick:Point .
      ?point rdf:type ?type
  }""")
  print(points)
  ```



  `brickschema` can add [VBIS](https://vbis.com.au/) tags to a Brick model easily

  ```python
  from brickschema import Graph
  g = Graph(load_brick=True)
  g.load_file("mybuilding.ttl")
  g.expand(profile="vbis")

  vbis_tags = g.query("""SELECT ?equip ?vbistag WHERE {
      ?equip  <https://brickschema.org/schema/1.1/Brick/alignments/vbis#hasVBISTag> ?vbistag
  }""")
  ```



  `brickschema` now supports interacting with a Graph object in a web browser. Executing `g.serve(<http address>)` on a graph object from your Python script or interpreter will start a webserver listening (by default) at http://localhost:8080 . This uses [Yasgui](https://yasgui.triply.cc/) to provide a simple web interface supporting SPARQL queries and inference.

  To use this feature, install `brickschema` with the `web` feature enabled:

  ```
  pip install brickschema[web]
  ```



  The module utilizes the [pySHACL](https://github.com/RDFLib/pySHACL) package to validate a building ontology against the Brick Schema, its default constraints (shapes) and user provided shapes.

  ```python
  from brickschema import Graph

  g = Graph(load_brick=True)
  g.load_file('myBuilding.ttl')
  valid, _, _ = g.validate()
  print(f"Graph is valid? {valid}")


  external = Graph()
  external.load_file("other_shapes.ttl")
  valid, _, _ = g.validate(shape_graphs=[external])
  print(f"Graph is valid? {valid}")
  ```

  The module provides a command
  `brick_validate` similar to the `pyshacl` command.  The following command is functionally
  equivalent to the code above.
  ```bash
  brick_validate myBuilding.ttl -s other_shapes.ttl
  ```



  To use `brickify`, install `brickschema` with the `[brickify]` feature enabled:

  ```
  pip install brickschema[brickify]
  ```

  **Usage**:

  ```console
  $ brickify [OPTIONS] SOURCE
  ```

  **Arguments**:

  * `SOURCE`: Path/URL to the source file  [required]

  **Options**:

  * `--input-type TEXT`: Supported input types: rac, table, rdf, haystack-v4
  * `--brick PATH`: Brick.ttl
  * `--config PATH`: Custom configuration file
  * `--output PATH`: Path to the output file
  * `--serialization-format TEXT`: Supported serialization formats: turtle, xml, n3, nt, pretty-xml, trix, trig and nquads  [default: turtle]
  * `--minify / --no-minify`: Remove inferable triples  [default: False]
  * `--input-format TEXT`: Supported input formats: xls, csv, tsv, url, turtle, xml, n3, nt, pretty-xml, trix, trig and nquads  [default: turtle]
  * `--building-prefix TEXT`: Prefix for the building namespace  [default: bldg]
  * `--building-namespace TEXT`: The building namespace  [default: https://example.com/bldg#]
  * `--site-prefix TEXT`: Prefix for the site namespace  [default: site]
  * `--site-namespace TEXT`: The site namespace  [default: https://example.com/site#]
  * `--install-completion`: Install completion for the current shell.
  * `--show-completion`: Show completion for the current shell, to copy it or customize the installation.
  * `--help`: Show this message and exit.

  Usage examples: [brickify](tests/data/brickify).



  Brick requires Python >= 3.6. We use [pre-commit hooks](https://pre-commit.com/) to automatically run code formatters and style checkers when you commit.

  Use [Poetry](https://python-poetry.org/docs/) to manage packaging and dependencies. After installing poetry, install dependencies with:

  ```bash
  poetry install
  ```

  Enter the development environment with the following command (this is analogous to activating a virtual environment.

  ```bash
  poetry shell
  ```

  On first setup, make sure to install the pre-commit hooks for running the formatting and linting tools:

  ```bash

  pre-commit install
  ```

  Run tests to make sure build is not broken

  ```bash

  make test
  ```



  Docs are written in reStructured Text. Make sure that you add your package requirements to `docs/requirements.txt`


pkgId: d31f4c0a8bf24b3cdd31f4bbd685d9ffa99133ec75a2547f2e6234957e4dfdff
name: python-brickschema-rdflib-sqlalchemy
arch: src
version: 0.6.1
epoch: 0
release: 1
summary: rdflib extension adding SQLAlchemy as an AbstractSQLStore back-end store
url: http://github.com/gtfierro/rdflib-sqlalchemy
rpm_license: BSD
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brickschema-rdflib-sqlalchemy-0.6.1-1.src.rpm
checksum_type: sha256
description:
      SQLAlchemy store formula-aware implementation.
      It stores its triples in the following partitions:

      * Asserted non rdf:type statements
      * Asserted rdf:type statements (in a table which models Class membership).
        The motivation for this partition is primarily improved query speed and
        scalability as most graphs will always have more rdf:type statements than
        others.
      * All Quoted statements

      In addition it persists namespace mappings in a separate table


pkgId: 2a4c5d5480dedd4e7668a8dd7b6380354c230867f30b097f86cfe95907e8e9a8
name: python-bridge-utils
arch: src
version: 0.4.1
epoch: 0
release: 1
summary: bridge (contract game) utils for PBN & xinrui & bbo
url: https://gitlab.com/xrgopher/bridge-utils
rpm_license: MIT License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-bridge-utils-0.4.1-1.src.rpm
checksum_type: sha256
description:
  There are several utity tools for writing bridge articles



  * support xinrui url, bbo lin url (bbo soon)
  * generate well tuned latex/html bridge layout (card diagram)
  * generate all kinds of ebook (`.pdf`/`.mobi`/`.epub`/`.html`/`.latex`) with related toolchains (`pandoc`,`multimarkdown`)

  It contains several subpackage

  * xin2pbn
  * pbn2html
  * mdbridge (mdbridge2latex, mdbrdige2html)



  ````
  pip install bridge-utils
  ````





  xinrui bridge online url to pbn converter

  xinrui url looks like [this](http://www.xinruibridge.com/deallog/DealLog.html?bidlog=P%3BP,1S,X,2S%3BP,P,X,P%3B3C,P,4C,P%3B5C,P,P,P%3B&playlog=W:TH,KH,AH,4H%3BE:TS,KS,AS,6C%3BN:3H,2H,9H,8H%3BS:TD,KD,AD,7D%3BN:3D,9D,2C,2D%3BS:3C,4C,TC,5C%3BN:6D,5D,QC,4D%3BS:7C,KC,AC,8C%3BN:&deal=T96.A62.J975.985%20KQ832.954.T.Q732%20AJ754.T8.K842.K4%20.KQJ73.AQ63.AJT6&vul=NS&dealer=E&contract=5C&declarer=S&wintrick=12&score=620&str=%E7%BE%A4%E7%BB%84IMP%E8%B5%9B%2020201121%20%E7%89%8C%E5%8F%B7%202/8&dealid=984602529&pbnid=344008254), it can be converted to standard pbn files [output.pbn](output.pbn)



  ````
  pip install xin2pbn
  xin2pbn "url"
  xin2pbn "local.html"
  ````



  ````
  $ xin2pbn "http://www.xinruibridge.com/deallog/DealLog.html?bidlog=P%3BP,1S,X,2S%3BP,P,X,P%3B3C,P,4C,P%3B5C,P,P,P%3B&playlog=W:TH,KH,AH,4H%3BE:TS,KS,AS,6C%3BN:3H,2H,9H,8H%3BS:TD,KD,AD,7D%3BN:3D,9D,2C,2D%3BS:3C,4C,TC,5C%3BN:6D,5D,QC,4D%3BS:7C,KC,AC,8C%3BN:&deal=T96.A62.J975.985%20KQ832.954.T.Q732%20AJ754.T8.K842.K4%20.KQJ73.AQ63.AJT6&vul=NS&dealer=E&contract=5C&declarer=S&wintrick=12&score=620&str=%E7%BE%A4%E7%BB%84IMP%E8%B5%9B%2020201121%20%E7%89%8C%E5%8F%B7%202/8&dealid=984602529&pbnid=344008254"
  write to file output.pbn
  write to file output.html

  $ curl -O https://isoliu.gitlab.io/book2020/web/1-chapter2-B01-zdjs.html
    % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                   Dload  Upload   Total   Spent    Left  Speed
  100  5054  100  5054    0     0  11512      0 --:--:-- --:--:-- --:--:-- 11512
  $ xin2pbn 1-chapter2-B01-zdjs.html
  [b'https://isoliu.gitlab.io/deallog/DealLog.html?bidlog=1D,1S,P;2D,3C,P,P;4S,P,P,X;P,P,P&amp;playlog=E:5D,KD,2D,6D;S:3H,5H,8H,7H;N:8S,TS,AS,3D;S:4C,KC,3C,2C;W:8D,7D,2S,9D;E:8C,JC,AC,5C;W:QD,TH,5S,4D;E:6H,9H,KH,AH;N:&amp;deal=.K5.QJT832.AK976%20KQ874.AT8.76.Q53%20JT652.7642.5.T82%20A93.QJ93.AK94.J4&amp;vul=All&amp;dealer=W&amp;contract=4SX&amp;declarer=N&amp;wintrick=9&amp;score=-200&amp;str=%E9%94%A6%E6%A0%87%E8%B5%9B%20%E7%AC%AC12%E8%BD%AE%20%E7%89%8C%E5%8F%B7%204/12&amp;dealid=653117488&amp;pbnid=127397878', b'https://isoliu.gitlab.io/deallog/DealLog.html?bidlog=1D,1S,P;2D,3C,P,P;4S,P,P,X;P,P,P&amp;playlog=E:5D,AD,2D,6D;S:QH,KH,AH,7H;N:KS,2S,3S,3D;N:4S,TS,AS,8D;S:3H,5H,8H,2H;N:TH,6H,JH,7C;S:9H,6C,7D,4H;S:4C,KC,3C,2C;W:AC,5C,8C,JC;W:QD,QS,TC,4D;N:&amp;deal=.K5.QJT832.AK976%20KQ874.AT8.76.Q53%20JT652.7642.5.T82%20A93.QJ93.AK94.J4&amp;vul=All&amp;dealer=W&amp;contract=4SX&amp;declarer=N&amp;wintrick=10&amp;score=790&amp;str=%E9%94%A6%E6%A0%87%E8%B5%9B%20%E7%AC%AC12%E8%BD%AE%20%E7%89%8C%E5%8F%B7%204/12&amp;dealid=653247876&amp;pbnid=127397878']
  write to file ./1-chapter2-B01-zdjs-01.pbn
  write to file ./1-chapter2-B01-zdjs-02.pbn

  $ cat 1-cha*.pbn > all.pbn
  ````

  Open `output.html` can browse the playing log locally



  original source in xinrui UI

  ![](xinrui.png)

  The outputed pbn can be viewed inside bridgecomposer & pbnjview

  ![](bridgecomposer.png)
  ![](pbnjview.png)





  This is for http://xrgopher.gitee.io/studentbridge

  ````
  zyj-update README.txt
  ````

  Using README.txt, all the materials are combined into `README.md` with xinrui links, then generate HTMLs

  ````
  zyj-convert README.md
  ````

  Then `README.html` and `README.pbn.html` are generated



  * Ramsey's article for xinrui bridge (Chinese), see [ramsey.md](https://xrgopher.gitlab.io/mdbridge/ramsey.md) and [ramsey.pdf](https://xrgopher.gitlab.io/mdbridge/ramsey.pdf)

  You need install [MulitMarkdown](https://fletcherpenney.net/multimarkdown/download/) first



  Generally, follow below steps

  * write it in special format with markdown
  * use `mdbridge` tool to generate intermediate markdown file
  * use `multimarkdown` or `pandoc` to generate related format files
  * generate final ebook

  See below for latex

  ````
  $ mdbrdige2latex sample # download sample files ramsey.md, meta.txt
  $ mdbridge2latex ramsey.md
  ramsey.bridge-tex is created
  $ multimarkdown -t latex meta.txt ramsey.bridge-tex -o ramsey.tex
  $ xelatex ramsey.tex # use overleaf if u don't have latex env.
  ````

  Then you can edit the file in [overleaf](https://www.overleaf.com) like [ramsey.tex@overleaf.com](https://www.overleaf.com/read/kzwczwjqhxhr)

  See below for html

  ````
  $ mdbridge2html ramsey.md
  processing ramsey.md -> ramsey.bridge
  write to file interesting.pbn
  write to file interesting.pbn
  $ multimarkdown.exe  -t html ramsey.bridge -o ramsey.html
  ````







  <pre lang="bridge">
  http://www.xinruibridge.com/deallog/DealLog.html?bidlog=P,2N,P%3B3C,P,3N,P%3B6N,P,P,P%3B&playlog=E:KD,3D,4D,JD%3BE:2D,5D,7D,AD%3BN:JS,6S,5S,8S%3BN:KS,4S,7S,2S%3BN:3S,TS,AS,8H%3BS:QS,TD,4C,9S%3BS:KH,JH,4H,2H%3BS:AH,TH,9H,3H%3BS:QH,9D,8C,5H%3BS:2C,JC,QC,6C%3BN:KC,9C,6D,5C%3BN:AC,7H,6H,3C%3BN:7C,QD,8D,TC%3B&deal=82.JT8.T974.JT53%20KJ3.94.AJ.AKQ874%20T964.7532.KQ2.96%20AQ75.AKQ6.8653.2&vul=All&dealer=W&contract=6N&declarer=N&wintrick=11&score=-100&str=%E7%BE%A4%E7%BB%84IMP%E8%B5%9B%2020201209%20%E7%89%8C%E5%8F%B7%204/8&dealid=995050099&pbnid=345464272
  auction
  </pre>



  `deal|cards=NS|ul="<str>"|ll=<str>|ur=<str>`

  Two-Hand Diagram

  <pre lang="bridge">
  deal|cards=NS
  </pre>

  All-Hands Diagram

  <pre lang="bridge">
  deal
  </pre>

  Partial deal

  <pre lang="bridge">
  deal=.xxxx..xxx&.T4.A.AK87&-&.AKQ6.865.
  </pre>

  Partial deal with extra information

  <pre lang="bridge">
  deal=.xxxx..xxx&.94.A.AK87&-&.AKQ6.865.|ll="NS 4/12&EW 0"|ur="match 4/8"
  </pre>



  * Ramsey @ xinrui : mainly for latex template and tune the card diagrams



  * http://www.rpbridge.net/7z69.htm


pkgId: 60f0f5ae075c1135a216ebaa5a72d2acbd6b3941627c3ff0e14cf8e3d419e9f3
name: python-bridgecrew
arch: src
version: 3.2.257
epoch: 0
release: 1
summary: Infrastructure as code static analysis
url: https://github.com/bridgecrewio/bridgecrew
rpm_license: Apache License 2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-bridgecrew-3.2.257-1.src.rpm
checksum_type: sha256
description:
  [![build status](https://github.com/bridgecrewio/bridgecrew-py/workflows/release/badge.svg)](https://github.com/bridgecrewio/bridgecrew-py/actions?query=workflow%3Arelease)
  [![PyPI](https://img.shields.io/pypi/v/bridgecrew)](https://pypi.org/project/checkov/)

  Wraps checkov with a bridgecrew cli (does exactly the same)


pkgId: 7c59e6fb85597eb110a238d10982720c1b40e0bd297f0f66e9c5ef7b682cef60
name: python-bridgekeeper
arch: src
version: 0.9
epoch: 0
release: 1
summary: Django permissions that work with QuerySets.
url: https://bridgekeeper.leigh.party/
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-bridgekeeper-0.9-1.src.rpm
checksum_type: sha256
description:
      | Who would cross the Bridge of Death
      | must answer me these questions three,
      | ere the other side he see.
      -- The Bridgekeeper, *Monty Python and the Holy Grail*
  Bridgekeeper is a permissions library for Django_ projects, where permissions are defined in your code, rather than in your database.
  It's heavily inspired by django-rules_, but with one important difference: **it works on QuerySets as well as individual model instances**.
  This means that you can efficiently show a list of all of the model instances that your user is allowed to edit, for instance, without having your permission-checking code in two different places.
  Bridgekeeper is tested on Django 2.2 and 3.0 on all Python versions Django supports, and is licensed under the MIT License.


pkgId: b44b82dfcd46f4cfb0216332abf88f14b77864a0910634269d76b19202fc7c43
name: python-bridges
arch: src
version: 3.4.4
epoch: 0
release: 1
summary: Bridging Real-world Infrastructure Designed to Goal-align, Engage, and Stimulate, an NSF TUES
url: https://github.com/BridgesUNCC/bridges-python
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-bridges-3.4.4-1.src.rpm
checksum_type: sha256
description:
  This is the Python implementation of the BRIDGES API

  Authors: Matthew Mcquaigue, David Burlinson, Kalpathi Subramanian

  Date: June 2018



  Recommended installation from [pip](https://pypi.org/project/bridges/)
  `pip install bridges`


  To install from this repository
  `cd path/to/directory`
  `python setup.py install`



  read [this](packaging.md)


pkgId: f3d7f5c5a433f0955f0575cda67c3b7f5fc2c25d323a6df5e51cb24e89e90390
name: python-bridgescaler
arch: src
version: 0.7.1
epoch: 0
release: 1
summary: Tool to automagically save scikit-learn scaler properties to a portable, readable format.
url: https://github.com/NCAR/bridgescaler
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-bridgescaler-0.7.1-1.src.rpm
checksum_type: sha256
description:
  Bridge your scikit-learn-style scaler parameters between Python sessions and users.
  Bridgescaler allows you to save the properties of a scikit-learn-style scaler object
  to a json file, and then repopulate a new scaler object with the same properties.



  * scikit-learn
  * numpy
  * pandas
  * xarray
  * pytdigest


  For a stable version of bridgescaler, you can install from PyPI.
  ```bash
  pip install bridgescaler
  ```

  For the latest version of bridgescaler, install from github.
  ```bash
  git clone https://github.com/NCAR/bridgescaler.git
  cd bridgescaler
  pip install .
  ```


  bridgescaler supports all the common scikit-learn scaler classes:
  * StandardScaler
  * RobustScaler
  * MinMaxScaler
  * MaxAbsScaler
  * QuantileTransformer
  * PowerTransformer
  * SplineTransformer

  First, create some synthetic data to transform.
  ```python
  import numpy as np
  import pandas as pd


  locs = np.array([0, 5, -2, 350.5], dtype=np.float32)
  scales = np.array([1.0, 10, 0.1, 5000.0])
  names = ["A", "B", "C", "D"]
  num_examples = 205
  x_data_dict = {}
  for l in range(locs.shape[0]):
      
      x_data_dict[names[l]] = np.random.normal(loc=locs[l], scale=scales[l], size=num_examples)
  x_data = pd.DataFrame(x_data_dict)
  ```

  Now, let's fit and transform the data with StandardScaler.
  ```python
  from sklearn.preprocessing import StandardScaler
  from bridgescaler import save_scaler, load_scaler

  scaler = StandardScaler()
  scaler.fit_transform(x_data)
  filename = "x_standard_scaler.json"

  save_scaler(scaler, filename)


  new_scaler = load_scaler(filename) # new_scaler is a StandardScaler object
  ```

  The distributed scalers allow you to calculate scaling
  parameters on different subsets of a dataset and then combine the scaling factors
  together to get representative scaling values for the full dataset. Distributed
  Standard Scalers, MinMax Scalers, and Quantile Transformers have been implemented and work with both tabular
  and muliti-dimensional patch data in numpy, pandas DataFrame, and xarray DataArray formats.
  By default, the scaler assumes your channel/variable dimension is the last
  dimension, but if `channels_last=False` is set in the `__init__`, `transform`,
  or `inverse_transform` methods, then the 2nd dimension is assumed to be the variable
  dimension. It is possible to fit data with one ordering and then
  transform it with a different one.

  For large datasets, it may be expensive to redo the scalers if you want to use a
  subset or different ordering of variables. However, in bridgescaler, the
  Distributed Scalers all support arbitrary ordering and subsets of variables for transforms if
  the input data are in a Xarray DataArray or Pandas DataFrame with variable
  names that match the original data.

  Example:
  ```python
  from bridgescaler.distributed import DStandardScaler
  import numpy as np

  x_1 = np.random.normal(0, 2.2, (20, 5, 4, 8))
  x_2 = np.random.normal(1, 3.5, (25, 4, 8, 5))

  dss_1 = DStandardScaler(channels_last=False)
  dss_2 = DStandardScaler(channels_last=True)
  dss_1.fit(x_1)
  dss_2.fit(x_2)
  dss_combined = np.sum([dss_1, dss_2])

  dss_combined.transform(x_1, channels_last=False)
  ```


  The group scalers use the same scaling parameters for a group of similar
  variables rather than scaling each column independently. This is useful for situations where variables are related,
  such as temperatures at different height levels.

  Groups are specified as a list of column ids, which can be column names for pandas dataframes or column indices
  for numpy arrays.

  For example:
  ```python
  from bridgescaler.group import GroupStandardScaler
  import pandas as pd
  import numpy as np
  x_rand = np.random.random(size=(100, 5))
  data = pd.DataFrame(data=x_rand,
                      columns=["a", "b", "c", "d", "e"])
  groups = [["a", "b"], ["c", "d"], "e"]
  group_scaler = GroupStandardScaler()
  x_transformed = group_scaler.fit_transform(data, groups=groups)
  ```

  "a" and "b" are a single group and all values of both will be included when calculating the mean and standard
  deviation for that group.


  The deep scalers are designed to scale 2 or 3-dimensional fields input into a
  deep learning model such as a convolutional neural network. The scalers assume
  that the last dimension is the channel/variable dimension and scales the values accordingly.
  The scalers can support 2D or 3D patches with no change in code structure. Support is provided for
  DeepStandardScaler and DeepQuantileTransformer.

  Example:
  ```python
  from bridgescaler.deep import DeepStandardScaler
  import numpy as np
  np.random.seed(352680)
  n_ex = 5000
  n_channels = 4
  dim = 32
  means = np.array([1, 5, -4, 2.5], dtype=np.float32)
  sds = np.array([10, 2, 43.4, 32.], dtype=np.float32)
  x = np.zeros((n_ex, dim, dim, n_channels), dtype=np.float32)
  for chan in range(n_channels):
      x[..., chan] = np.random.normal(means[chan], sds[chan], (n_ex, dim, dim))
  dss = DeepStandardScaler()
  dss.fit(x)
  x_transformed = dss.transform(x)
  ```


pkgId: 964e3d9d957965c5a51ec2fe223fddbaa6009eba0e8d2872df44adb621716272
name: python-bridgezoo
arch: src
version: 0.0.2
epoch: 0
release: 1
summary: A Gymnasium style bridge environment.
url: https://pypi.org/project/bridgezoo/
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-bridgezoo-0.0.2-1.src.rpm
checksum_type: sha256
rpm_license:
  This software is under the MIT Licence ======================================  Copyright (c) 2010 openpyxl  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: eb1eae7c117b4be462b100005cbb5a7dbb3aabd291cddd97a2be54dc0ed84652
name: python-briefcase
arch: src
version: 0.3.20
epoch: 0
release: 1
summary: Tools to support converting a Python project into a standalone native application.
url: https://beeware.org/briefcase
rpm_license: New BSD
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-briefcase-0.3.20-1.src.rpm
checksum_type: sha256
description:
  |pyversions| |version| |maturity| |license| |ci| |social|
  Briefcase is a tool for converting a Python project into a standalone native
  application. You can package projects for:
  * Mac
  * Windows
  * Linux
  * iPhone/iPad
  * Android
  * Web
  Support for AppleTV, watchOS, and wearOS deployments is planned.


pkgId: 5026f5ceaefe388f0d1afc2aaac5b382f56970ca04406f2f7002c95e113c4e9c
name: python-briefed-people-utils
arch: src
version: 0.6.9
epoch: 0
release: 1
summary: Tools to support collect and send publically available data to Briefed.
url: https://Briefed.eu
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-briefed-people-utils-0.6.9-1.src.rpm
checksum_type: sha256
description:
  This project is for supporting serverless apps collecting publicly available
  data and sending that data to https://Briefed.eu.

  python3 setup.py sdist bdist_wheel
  twine upload dist/* -r pypi


pkgId: 0a3b813139fa044d09ee31b91b39e8df7a60b4f00614826a9762c5114f0dfdc2
name: python-briefer
arch: src
version: 0.0.14
epoch: 0
release: 1
url: https://briefer.cloud
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-briefer-0.0.14-1.src.rpm
checksum_type: sha256
summary:
  Python notebooks and dashboards in a single place. Create powerful and flexible dashboards using code, or build beautiful Notion-like notebooks and share them with your team.

description:
  <p align="center">
    We can help you deploy Briefer for free. <a href="https://calendly.com/lucasfcosta/briefer-deployment">Book a time here</a>.

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


pkgId: c00f0c2be8d5b33b229d165dcab62267cd1d3d13cf995fa024dbdb1580b2de55
name: python-brightest-path-lib
arch: src
version: 1.0.56
epoch: 0
release: 1
summary: A library of path-finding algorithms to find the brightest path between points in an image.
url: https://github.com/mapmanager/brightest-path-lib
rpm_license: GNU General Public License, Version 3
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brightest-path-lib-1.0.56-1.src.rpm
checksum_type: sha256
description:
  [![Python](https://img.shields.io/badge/python-3.9|3.10|3.11-blue.svg)](https://www.python.org/downloads/release/python-3111/)
  [![tests](https://github.com/mapmanager/brightest-path-lib/workflows/Test/badge.svg)](https://github.com/mapmanager/brightest-path-lib/actions)
  [![codecov](https://codecov.io/github/mapmanager/brightest-path-lib/branch/main/graph/badge.svg?token=0ZR226588I)](https://codecov.io/github/mapmanager/brightest-path-lib)
  [![OS](https://img.shields.io/badge/OS-Linux|Windows|macOS-blue.svg)]()
  [![License](https://img.shields.io/badge/license-GPLv3-blue)](https://github.com/mapmanager/brightest-path-lib/blob/main/LICENSE)
  [![PyPI](https://img.shields.io/pypi/v/brightest-path-lib.svg)](https://pypi.org/project/brightest-path-lib/)
  <!-- [![Changelog](https://img.shields.io/github/v/release/mapmanager/brightest-path-lib?include_prereleases&label=changelog)](https://github.com/mapmanager/brightest-path-lib/releases) -->

  A Python package of path-finding algorithms to find the brightest path between points in an image.



  To install and get started with the `brightest-path-lib`, please visit the [documentation website](https://mapmanager.net/brightest-path-lib/installation/).

  For more detailed instructions on how to use the `brightest-path-lib`, please see the [API documentation](https://mapmanager.net/brightest-path-lib/api_docs/).



  Contributions are very welcome. Tests can be run with `pytest`, please ensure the coverage at least stays the same before you submit a pull request.

  To contribute to this package, first checkout the code. Then create a new virtual environment:

   - With venv
      python -m venv brightest-env
      source brightest-env/bin/activate
   - With conda
      conda create -y -n brightest-env python=3.9
      conda activate brightest-env

  Now install the package with the testing dependencies:

      cd brightest-path-lib
      pip install -e '.[test]'

  To run the tests:

      pytest



  If you have any suggestions or encounter any problems, please file an [issue](https://github.com/mapmanager/brightest-path-lib/issues) along with a detailed description.



  Distributed under the terms of the GNU GPL v3.0 license, "brightest-path-lib" is free and open source software.


pkgId: fa796d396847d9dbf987f55d88f43d5ef330de6c47323afcf16fedd6f55b3ef1
name: python-brighteyes-ism
arch: src
version: 1.3.4
epoch: 0
release: 1
summary: A toolbox for analysing and simulating ISM images
url: https://github.com/VicidominiLab/brighteyes-ism
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brighteyes-ism-1.3.4-1.src.rpm
checksum_type: sha256
description:
  You can install `brighteyes-ism` via [pip] directly from GitHub:
      pip install git+https://github.com/VicidominiLab/BrightEyes-ISM
  or using the version on [PyPI]:
      pip install brighteyes-ism
  It requires the following Python packages
      numpy
  	scipy
      matplotlib
  	scikit-image
      scikit-learn
  	poppy
  	PyCustomFocus==2.*
      h5py
      tqdm
  	statsmodels
  	matplotlib-scalebar

  You can find some examples of usage here:
  https://github.com/VicidominiLab/BrightEyes-ISM/tree/main/examples
  You can read the manual of this package on Read the Docs:
  https://brighteyes-ism.readthedocs.io

  If you find BrightEyes-ISM useful for your research, please cite it as:
  _Zunino, A., Slenders, E., Fersini, F. et al. Open-source tools enable accessible and advanced image scanning microscopy data analysis. Nat. Photon. (2023). https://doi.org/10.1038/s41566-023-01216-x_

  Distributed under the terms of the [GNU GPL v3.0] license,
  "BrightEyes-ISM" is free and open source software

  You want to contribute? Great!
  Contributing works best if you creat a pull request with your changes.
  1. Fork the project.
  2. Create a branch for your feature: `git checkout -b cool-new-feature`
  3. Commit your changes: `git commit -am 'My new feature'`
  4. Push to the branch: `git push origin cool-new-feature`
  5. Submit a pull request!
  If you are unfamilar with pull requests, you find more information on pull requests in the
   [github help](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests)

  If you encounter any problems, please [file an issue] along with a detailed description.
  [MIT]: http://opensource.org/licenses/MIT
  [BSD-3]: http://opensource.org/licenses/BSD-3-Clause
  [GNU GPL v3.0]: http://www.gnu.org/licenses/gpl-3.0.txt
  [GNU LGPL v3.0]: http://www.gnu.org/licenses/lgpl-3.0.txt
  [Apache Software License 2.0]: http://www.apache.org/licenses/LICENSE-2.0
  [Mozilla Public License 2.0]: https://www.mozilla.org/media/MPL/2.0/index.txt
  [file an issue]: https://github.com/VicidominiLab/brighteyes-ism/issues
  [tox]: https://tox.readthedocs.io/en/latest/
  [pip]: https://pypi.org/project/pip/
  [PyPI]: https://pypi.org/project/brighteyes-ism/


pkgId: ebe7697efec21de42f8dd5f1c544183b5830e26779ad2ef91fb79a7b6efd4394
name: python-brightnetwork-algoliasearch-django
arch: src
version: 3.0.0
epoch: 0
release: 1
summary: Algolia Search integration for Django
url: https://github.com/brightnetwork/algoliasearch-django
rpm_license: MIT License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brightnetwork-algoliasearch-django-3.0.0-1.src.rpm
checksum_type: sha256
description:
  <p align="center">
    <a href="https://www.algolia.com">
      <img alt="Algolia for Django" src="https://raw.githubusercontent.com/algolia/algoliasearch-client-common/master/banners/django.png" >
    </a>

    <h4 align="center">The perfect starting point to integrate <a href="https://algolia.com" target="_blank">Algolia</a> within your Django project</h4>

    <p align="center">
      <a href="https://travis-ci.org/algolia/algoliasearch-django"><img src="https://travis-ci.org/algolia/algoliasearch-django.svg?branch=master" alt="Build Status"></img></a>
      <a href="https://coveralls.io/r/algolia/algoliasearch-django"><img src="https://coveralls.io/repos/algolia/algoliasearch-django/badge.svg?branch=master" alt="Coverage Status"></img></a>
      <a href="http://badge.fury.io/py/algoliasearch-django"><img src="https://badge.fury.io/py/algoliasearch-django.svg?branch=master" alt="PyPi Version"></img></a>
    </p>
  </p>


  <p align="center">
    <a href="https://www.algolia.com/doc/api-client/getting-started/install/go/" target="_blank">Documentation</a>  •
    <a href="https://discourse.algolia.com" target="_blank">Community Forum</a>  •
    <a href="http://stackoverflow.com/questions/tagged/algolia" target="_blank">Stack Overflow</a>  •
    <a href="https://github.com/algolia/algoliasearch-django/issues" target="_blank">Report a bug</a>  •
    <a href="https://www.algolia.com/support" target="_blank">Support</a>
  </p>



  You can find the full reference on [Algolia's website](https://www.algolia.com/doc/framework-integration/django/).



  1. **[Setup](#setup)**
      * [Introduction](#introduction)
      * [Install](#install)
      * [Setup](#setup)
      * [Quick Start](#quick-start)

  1. **[Commands](#commands)**
      * [Commands](#commands)

  1. **[Search](#search)**
      * [Search](#search)

  1. **[Geo-Search](#geo-search)**
      * [Geo-Search](#geo-search)

  1. **[Tags](#tags)**
      * [Tags](#tags)

  1. **[Options](#options)**
      * [Custom <code>objectID</code>](#custom-codeobjectidcode)
      * [Custom index name](#custom-index-name)
      * [Field Preprocessing and Related objects](#field-preprocessing-and-related-objects)
      * [Index settings](#index-settings)
      * [Restrict indexing to a subset of your data](#restrict-indexing-to-a-subset-of-your-data)
      * [Multiple indices per model](#multiple-indices-per-model)
      * [Temporarily disable the auto-indexing](#temporarily-disable-the-auto-indexing)

  1. **[Aggregators](#aggregators)**
      * [Aggregators](#aggregators)

  1. **[Tests](#tests)**
      * [Run Tests](#run-tests)










  This package lets you easily integrate the Algolia Search API to your [Django](https://www.djangoproject.com/) project. It's based on the [algoliasearch-client-python](https://github.com/algolia/algoliasearch-client-python) package.

  You might be interested in this sample Django application providing a typeahead.js based auto-completion and Google-like instant search: [algoliasearch-django-example](https://github.com/algolia/algoliasearch-django-example)

  Compatible with **Python 3.5+** and **Django 2.2+**



  ```sh
  pip install algoliasearch-django
  ```



  In your Django settings, add `algoliasearch_django` to `INSTALLED_APPS` and add these two settings:

  ```python
  ALGOLIA = {
      'APPLICATION_ID': 'MyAppID',
      'API_KEY': 'MyApiKey'
  }
  ```

  There are several optional settings:

  * `INDEX_PREFIX`: prefix all indices. Use it to separate different applications, like `site1_Products` and `site2_Products`.
  * `INDEX_SUFFIX`: suffix all indices. Use it to differentiate development and production environments, like `Location_dev` and `Location_prod`.
  * `AUTO_INDEXING`: automatically synchronize the models with Algolia (default to **True**).
  * `RAISE_EXCEPTIONS`: raise exceptions on network errors instead of logging them (default to **settings.DEBUG**).



  Create an `index.py` inside each application that contains the models you want to index.
  Inside this file, call `algoliasearch.register()` for each of the models you want to index:

  ```python


  import algoliasearch_django as algoliasearch

  from .models import YourModel

  algoliasearch.register(YourModel)
  ```

  By default, all the fields of your model will be used. You can configure the index by creating a subclass of `AlgoliaIndex` and using the `register` decorator:

  ```python


  from algoliasearch_django import AlgoliaIndex
  from algoliasearch_django.decorators import register

  from .models import YourModel

  @register(YourModel)
  class YourModelIndex(AlgoliaIndex):
      fields = ('name', 'date')
      geo_field = 'location'
      settings = {'searchableAttributes': ['name']}
      index_name = 'my_index'

  ```





  -   `python manage.py algolia_reindex`: reindex all the registered models. This command will first send all the record to a temporary index and then moves it.
      -   you can pass `--index` parameter to reindex a given index
  -   `python manage.py algolia_applysettings`: (re)apply the index settings.
  -   `python manage.py algolia_clearindex`: clear the index





  We recommend using our [InstantSearch.js library](https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/) to build your search
  interface and perform search queries directly from the end-user browser without going through your server.

  However, if you want to search from your backend you can use the `raw_search(YourModel, 'yourQuery', request_options)` method.
  It retrieves the raw JSON answer from the API, and accepts in `request_options` any
  [search parameters](https://www.algolia.com/doc/api-reference/search-api-parameters/).

  ```python
  from algoliasearch_django import raw_search

  request_options = { "hitsPerPage": 5 }
  response = raw_search(Contact, "jim", request_options)
  ```





  Use the `geo_field` attribute to localize your record. `geo_field` should be a callable that returns a tuple (latitude, longitude).

  ```python
  class Contact(models.model):
      name = models.CharField(max_length=20)
      lat = models.FloatField()
      lng = models.FloatField()

      def location(self):
          return (self.lat, self.lng)

  class ContactIndex(AlgoliaIndex):
      fields = 'name'
      geo_field = 'location'

  algoliasearch.register(Contact, ContactIndex)
  ```









  Use the `tags` attributes to add tags to your record. It can be a field or a callable.

  ```python
  class ArticleIndex(AlgoliaIndex):
      tags = 'category'
  ```

  At query time, specify `{ tagFilters: 'tagvalue' }` or `{ tagFilters: ['tagvalue1', 'tagvalue2'] }` as search parameters to restrict the result set to specific tags.









  You can choose which field will be used as the `objectID `. The field should be unique and can
      be a string or integer. By default, we use the `pk` field of the model.

  ```python
  class ArticleIndex(AlgoliaIndex):
      custom_objectID = 'post_id'
  ```



  You can customize the index name. By default, the index name will be the name of the model class.

  ```python
  class ContactIndex(algoliaindex):
      index_name = 'Enterprise'
  ```



  If you want to process a field before indexing it (e.g. capitalizing a `Contact`'s `name`),
  or if you want to index a [related object](https://docs.djangoproject.com/en/1.11/ref/models/relations/)'s
  attribute, you need to define **proxy methods** for these fields.



  ```python
  class Account(models.Model):
      username = models.CharField(max_length=40)
      service = models.CharField(max_length=40)

  class Contact(models.Model):
      name = models.CharField(max_length=40)
      email = models.EmailField(max_length=60)
      //...
      accounts = models.ManyToManyField(Account)

      def account_names(self):
          return [str(account) for account in self.accounts.all()]

      def account_ids(self):
          return [account.id for account in self.accounts.all()]
  ```



  ```python
  from algoliasearch_django import AlgoliaIndex

  class ContactIndex(AlgoliaIndex):
      fields = ('name', 'email', 'company', 'address', 'city', 'county',
                'state', 'zip_code', 'phone', 'fax', 'web', 'followers', 'account_names', 'account_ids')

      settings = {
          'searchableAttributes': ['name', 'email', 'company', 'city', 'county', 'account_names',
          }
  ```

  - With this configuration, you can search for a `Contact` using its `Account` names
  - You can use the associated `account_ids` at search-time to fetch more data from your
  model (you should **only proxy the fields relevant for search** to keep your records' size
  as small as possible)



  We provide many ways to configure your index allowing you to tune your overall index relevancy.
  All the configuration is explained on [our doc](https://www.algolia.com/doc/api-reference/api-parameters/).

  ```python
  class ArticleIndex(AlgoliaIndex):
      settings = {
          'searchableAttributes': ['name', 'description', 'url'],
          'customRanking': ['desc(vote_count)', 'asc(name)']
      }
  ```



  You can add constraints controlling if a record must be indexed or not. `should_index` should be a
  callable that returns a boolean.

  ```python
  class Contact(models.model):
      name = models.CharField(max_length=20)
      age = models.IntegerField()

      def is_adult(self):
          return (self.age >= 18)

  class ContactIndex(AlgoliaIndex):
      should_index = 'is_adult'
  ```



  It is possible to have several indices for a single model.

  - First, define all your indices that you want for a model:

  ```python
  from django.contrib.algoliasearch import AlgoliaIndex

  class MyModelIndex1(AlgoliaIndex):
      name = 'MyModelIndex1'
      ...

  class MyModelIndex2(AlgoliaIndex):
      name = 'MyModelIndex2'
      ...
  ```

  - Then, define a meta model which will aggregate those indices:

  ```python
  class MyModelMetaIndex(AlgoliaIndex):
      def __init__(self, model, client, settings):
          self.indices = [
              MyModelIndex1(model, client, settings),
              MyModelIndex2(model, client, settings),
          ]

      def raw_search(self, query='', request_options=None):
          res = {}
          for index in self.indices:
              res[index.name] = index.raw_search(query, request_options)
          return res

      def update_records(self, qs, batch_size=1000, **kwargs):
          for index in self.indices:
              index.update_records(qs, batch_size, **kwargs)

      def reindex_all(self, batch_size=1000):
          for index in self.indices:
              index.reindex_all(batch_size)

      def set_settings(self):
          for index in self.indices:
              index.set_settings()

      def clear_objects(self):
          for index in self.indices:
              index.clear_objects()

      def save_record(self, instance, update_fields=None, **kwargs):
          for index in self.indices:
              index.save_record(instance, update_fields, **kwargs)

      def delete_record(self, instance):
          for index in self.indices:
              index.delete_record(instance)
  ```

  - Finally, register this `AlgoliaIndex` with your `Model`:

  ```python
  import algoliasearch_django as algoliasearch
  algoliasearch.register(MyModel, MyModelMetaIndex)
  ```



  It is possible to temporarily disable the auto-indexing feature using the `disable_auto_indexing` context decorator:

  ```python
  from algoliasearch_django.decorators import disable_auto_indexing


  with disable_auto_indexing():
      MyModel.save()


  @disable_auto_indexing():
  my_method()


  with disable_auto_indexing(MyModel):
      MyModel.save()
      MyOtherModel.save()

  ```



  Aggregators allow multiple models to be included in a single index.

  ```python
  import algoliasearch_django as algoliasearch
  models = [...]
  algoliasearch.register_aggregator(models)
  ```

  For more control, `Aggregator` can be subclassed in the same way as `AlgoliaIndex`:

  ```py
  from algoliasearch_django import Aggregator

  class CustomAggregator(Aggregator)
      index_name = "MyAggregatorIndex"
      ...

  models = [...]
  algoliasearch.register_aggregator(models, CustomAggregator)
  ```







  To run the tests, first find your Algolia application id and Admin API key (found on the Credentials page).

  ```shell
  ALGOLIA_APPLICATION_ID={APPLICATION_ID} ALGOLIA_API_KEY={ADMIN_API_KEY} tox
  ```


  To override settings for some tests, use the [settings method](https://docs.djangoproject.com/en/1.11/topics/testing/tools/#django.test.SimpleTestCase.settings):
  ```python
  class OverrideSettingsTestCase(TestCase):
      def setUp(self):
          with self.settings(ALGOLIA={
              'APPLICATION_ID': 'foo',
              'API_KEY': 'bar',
              'AUTO_INDEXING': False
          }):
              algolia_engine.reset(settings.ALGOLIA)

      def tearDown(self):
          algolia_engine.reset(settings.ALGOLIA)

      def test_foo():
          
  ```


pkgId: ff574b68e5c9172ff6b985f9ae992f792e719232a2f010cadf532f4ee90d6bfe
name: python-brightside
arch: src
version: 0.6.13
epoch: 0
release: 1
summary: Provides a command dispatcher and task queue to support CQRS and microservices
url: https://github.com/BrighterCommand/Brightside
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brightside-0.6.13-1.src.rpm
checksum_type: sha256
description:
  Brightside is a command dispatcher and processor for Python. It also provides a work queue for asynchronous dispatch over a broker such as RabbitMQ.
  It is intended to work with Brighter, a C# command dispatcher and processor and allow polyglot solutions i.e. a Flask endpoint that sends work over a queue to a C# consumer or an ASP.NET WebAPI endpoint that sends a request over a work queue to a Python application.
  Brightside can also be used stand-alone as an opinionated alternative to libraries like Celery, which use RPC and not messaging.



  If you post messages via a Broker, and use alchemy_store then We need to know where the tables for the message store can be found;
  we don't create the database that contains them, we assume that you will do that, and so we need a connection string to find that
  database. To do this, we pick up the following environment variable:

  BRIGHTER_MESSAGE_STORE_URL

  If this environment variable is not set, we will generate an error


  The Docker Compose File is intended to provide sufficient infrastructure for you to run tests that require backing stores or Message Oriented Middleware.
  The testrunner.py script finds all test fixtures with the naming convention tests_* and runs them
  To run the tests just use ./run_rests.sh
  This shell script will docker-compose up the required infrastructure and a container for Brightside code and tests; that container is kept running with top
  Once running we use docker-exec to run the python test runner script

  [![Build Status](https://travis-ci.org/BrighterCommand/Brightside.svg?branch=master)](https://travis-ci.org/BrighterCommand/Brightside)


pkgId: 7484b0e74cee0aa0f7998e528436f716a222d4ada54ea758f69b37d95bceb802
name: python-brightway25
arch: src
version: 1.0.6
epoch: 0
release: 1
summary: Wrapper to document and install Brightway 2.5
url: https://github.com/brightway-lca/brightway25
rpm_license: BSD 3-clause
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brightway25-1.0.6-1.src.rpm
checksum_type: sha256
description:
  Brightway 2.5 is the next generation of the [Brightway2](https://brightway.dev/) framework for life cycle assessment. It provides new capabilities for cloud computing and model interaction, with the use of a new [processed data library](https://github.com/brightway-lca/bw_processing) and a separation between the calculation library and a library for [matrix construction and manipulation](https://github.com/brightway-lca/matrix_utils).
  Note that this library does not import anything, so running `from brightway25 import *` won't do anything useful. Instead, import each constituent library separately. A good default is:
  ```python
  import bw2analyzer as ba
  import bw2data as bd
  import bw2calc as bc
  import bw2io as bi
  import matrix_utils as mu
  import bw_processing as bp
  ```

  Brightway 2.5 can be use in parallel with Brightway 2, but each project must be either version 2 or 2.5. Brightway 2.5 projects have a different processed data format, and no longer use the `mapping` object.
  To upgrade an existing project to version 2.5, use the function `bw2data.projects.migrate_project_25()`.
  To maintain a clean separation between these two sets of projects, you can use some type of naming convention, or use an [environment variable](https://2.docs.brightway.dev/faq.html?#how-do-i-find-where-my-data-is-saved) for a new data directory.
  Official site:
  * https://brightway.dev
  Online documentation:
  * https://25.docs.brightway.dev/
  Development blog:
  * http://chris.mutel.org


pkgId: a72ec1081d5dc40bd921d33c7237c1cd4de872e40a15040c199e0015c88ec993
name: python-brigid
arch: src
version: 0.12.0
epoch: 0
release: 1
summary: Static site generator.
url: https://github.com/Tiendil/brigid
rpm_license: BSD-3-Clause
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brigid-0.12.0-1.src.rpm
checksum_type: sha256
description:
  A simple blog engine, but not simpler than it should be.



  - My blog: [tiendil.org](https://tiendil.org/) — look there to see all the features in action.
  - Sources of the blog: https://github.com/Tiendil/tiendil-org-content — look there to see how content is organized.

  Or run from the root of the repository:

  ```bash
  poetry install

  ./bin/dev-server.sh
  ```



  - Markdown as a source code for articles.
  - Multi-language support by design.
  - Mobile-friendly.
  - SEO-friendly.
  - No cookies.
  - Monolithic design: install and run. No need to look for plugins and themes.



  Brigid is not a static site generator, i.e. you should run brigid process to access the site. It gives some advantages over classic static site generators.

  - Redirects.
  - Nice tags filtering (for wide pages only, for now).
  - Detect language by headers.
  - Sentry reporting.
  - More features are coming.



  A very subjective list of design principles I follow in this project:

  - One solid, stable, simple, up-to-date solution. Just install and run.
  - Markdown won => use markdown as the primary source for posts.
  - TOML won => use TOML for metadata and frontmatter instead of YAML.
  - No unnecessary or unused features.
  - Design for not trivial posts: long, multilanguage, images, code, etc.
  - Server-side rendering is good. Use it as the primary approach.
  - Use minimum JS only when it is really required.
  - No CSS experiments, only stable verified solutions.


pkgId: 8fbf6237444d64cdba4831ca3c965ac64b27366cbf84e79f89943c07a0f113cb
name: python-brilws
arch: src
version: 3.9.1
epoch: 0
release: 1
summary: bril worksuite
url: https://github.com/xiezhen/brilws
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brilws-3.9.1-1.src.rpm
checksum_type: sha256
description:
  python package for working with BRIL data




  pip install brilws
  pip uninstall brilws


  export PYTHONPATH=$HOME/.local:$PYTHONPATH
  pip install --install-option="--prefix=$HOME/.local" brilws
  pip uninstall brilws




  python setup.py sdist
  python setup.py register -r pypi
  python setup.py sdist upload -r pypi


pkgId: 5098549b843755e13af5615d4b773af760932924498498860d950692868b5489
name: python-bring-api
arch: src
version: 0.9.0
epoch: 0
release: 1
summary: Unofficial package to access Bring! shopping lists API.
url: https://pypi.org/project/bring-api/
rpm_license: MIT License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-bring-api-0.9.0-1.src.rpm
checksum_type: sha256
description:
  [![PyPI version](https://badge.fury.io/py/bring-api.svg)](https://pypi.org/p/bring-api)

  An unofficial python package to access the Bring! shopping lists API.



  > This implementation of the api is derived from the generic python implementation by [eliasball](https://github.com/eliasball/python-bring-api), which uses the legacy version of the api. This fork has been synced last time on 2024-02-11 and diverges from that point on using the non-legacy version. The implementation of [eliasball](https://github.com/eliasball/python-bring-api) is a **minimal** python port of the [node-bring-api](https://github.com/foxriver76/node-bring-api) by [foxriver76](https://github.com/foxriver76). All credit goes to him for making this awesome API possible!



  The developers of this module are in no way endorsed by or affiliated with Bring! Labs AG, or any associated subsidiaries, logos or trademarks.



  `pip install bring-api`



  See below for usage examples. See [Exceptions](#exceptions) for API-specific exceptions and mitigation strategies for common exceptions.



  The API is based on the async HTTP library `aiohttp`.

  ```python
  import aiohttp
  import asyncio
  import logging
  import sys

  from bring_api import Bring

  logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

  async def main():
    async with aiohttp.ClientSession() as session:
      
      bring = Bring(session, "MAIL", "PASSWORD")
      
      await bring.login()

      
      lists = (await bring.load_lists())["lists"]

      
      await bring.save_item(lists[0]['listUuid'], 'Milk', 'low fat')

      
      await bring.save_item(lists[0]['listUuid'], 'Carrots')

      
      items = await bring.get_list(lists[0]['listUuid'])
      print(items)

      
      await bring.complete_item(lists[0]['listUuid'], 'Carrots')

      
      await bring.remove_item(lists[0]['listUuid'], 'Milk')

  asyncio.run(main())
  ```



  This method uses the newer API endpoint for adding, completing and removing items from a list, which is also used in the Bring App. The items can be identified by their uuid and therefore some things are possible that are not possible with the legacy endpoints like:

  - Add/complete/remove multiple items at once
  - Adding multiple items with the same Name but different specifications
  - You can work with a unique identifier for an item even before adding it to a list, just use uuid4 to generate a random uuid!

  Usage examples:



  When adding an item, the `itemId` is required, `spec` and `uuid` are optional. If you need a unique identifier before adding an item, you can just generate a uuid4.

  ```python
  item = {
    "itemId": "Cilantro",
    "spec": "fresh",
    "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
  }
  await bring.batch_update_list(
    lists[0]['listUuid'],
    item,
    BringItemOperation.ADD)
  ```



  When updating an item, use ADD operation again. The `itemId` is required and the item `spec` will be added/updated on the existing item on the list. For better matching an existing item (if there is more than one item with the same `itemId`), you can use it's unique identifier `uuid`.

  ```python
  item = {
    "itemId": "Cilantro",
    "spec": "dried",
    "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
  }
  await bring.batch_update_list(
    lists[0]['listUuid'],
    item,
    BringItemOperation.ADD)
  ```



  ```python

  items = [{
    "itemId": "Cilantro",
    "spec": "fresh",
    "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
  },
  {
    "itemId": "Parsley",
    "spec": "dried",
    "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
  }]
  await bring.batch_update_list(
    lists[0]['listUuid'],
    items,
    BringItemOperation.ADD)
  ```



  When adding items with the same name the parameter `uuid` is required, otherwise the previous item will be matched by `itemId` and it's specification will be overwritten

  ```python
  items = [
    {
      "itemId": "Cilantro",
      "spec": "100g, dried",
      "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
    },
      {
      "itemId": "Cilantro",
      "spec": "fresh",
      "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
    }
  ]
  await bring.batch_update_list(
    lists[0]['listUuid'],
    items,
    BringItemOperation.ADD)
  ```



  When removing or completing an item you must submit `itemId` and `uuid`, `spec` is optional. Only the `uuid` will not work. Leaving out the `uuid` and submitting `itemId` and `spec` will also work. When submitting only `itemId` the Bring API will match the oldest item.

  ```python
  await bring.batch_update_list(
    lists[0]['listUuid'],
    {"itemId": "Cilantro", "uuid" : "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"},
    BringItemOperation.REMOVE)

  await bring.batch_update_list(
    lists[0]['listUuid'],
    {"itemId": "Cilantro", "uuid" : "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"},
    BringItemOperation.COMPLETE)
  ```



  An item that is already on the list can be renamed by sending it's `uuid` with a changed `itemId`. But it is highly advised against it because the Bring App will behave weirdly as it does not refresh an items name, not even when force reloading (going to the top of the list and pulling down). Users have to close the list by going to the overview or closing the app and only then when the list is completely refreshed the change of the name will show up.

  ```python

  item = {
    "itemId": "Cilantro",
    "uuid" : "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
  }
  await bring.batch_update_list(
    lists[0]['listUuid'],
    item,
    BringItemOperation.ADD)


  item["itemId"] = "Coriander"
  await bring.batch_update_list(
    lists[0]['listUuid'],
    item,
    BringItemOperation.ADD)
  ```



  In case something goes wrong during a request, several exceptions can be thrown.
  They will either be BringRequestException, BringParseException, or BringAuthException, depending on the context. All inherit from BringException.



  With the async calls, you might encounter an error that another asyncio event loop is already running on the same thread. This is expected behavior according to the asyncio.run() [documentation](https://docs.python.org/3/library/asyncio-runner.html#asyncio.run). You cannot use more than one aiohttp session per thread, reuse the existing one!



  Due to a known issue in some versions of aiohttp when using Windows, you might encounter a similar error to this:

  ```python
  Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x00000000>
  Traceback (most recent call last):
    File "C:\...\py38\lib\asyncio\proactor_events.py", line 116, in __del__
      self.close()
    File "C:\...\py38\lib\asyncio\proactor_events.py", line 108, in close
      self._loop.call_soon(self._call_connection_lost, None)
    File "C:\...\py38\lib\asyncio\base_events.py", line 719, in call_soon
      self._check_closed()
    File "C:\...\py38\lib\asyncio\base_events.py", line 508, in _check_closed
      raise RuntimeError('Event loop is closed')
  RuntimeError: Event loop is closed
  ```

  You can fix this according to [this](https://stackoverflow.com/questions/68123296/asyncio-throws-runtime-error-with-exception-ignored) stackoverflow answer by adding the following line of code before executing the library:

  ```python
  asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
  ```



  Setup the dev environment using VSCode, is is highly recommended.

  ```bash
  python -m venv .venv
  source .venv/bin/activate
  pip install -r requirements_dev.txt
  ```

  Install [pre-commit](https://pre-commit.com)

  ```bash
  pre-commit install


  pre-commit run --all-files


  export EMAIL=...
  export PASSWORD=...
  export LIST=...
  python test.py
  ```

  Following VSCode integrations may be helpful:

  - [ruff](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff)
  - [mypy](https://marketplace.visualstudio.com/items?itemName=matangover.mypy)
  - [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint)



  It is only possible to release a _final version_ on the `main` branch. For it to pass the gates of the `publish` workflow, it must have the same version in the `tag`, the `setup.cfg`, the `bring_api/__init__.py` and an entry in the `CHANGELOG.md` file.

  To release a prerelease version, no changelog entry is required, but it can only happen on a feature branch (**not** `main` branch). Also, prerelease versions are marked as such in the github release page.





  * Add type hints for item attributes (purchase conditions)
  * Minor code quality improvements, fix typos and upgrade type annotations



  * Reload locales after setting list language to ensure all required article translations are available



  * **New API method:** `set_list_article_language` sets the article language for a specified shopping list.



  * Change `name` and `photoPath` in type definitions for `BringSyncCurrentUserResponse` and `BringAuthResponse` to optional parameters
  * Add py.typed file so that type checkers can use type annotations



  * fix bug in debug log message.



  * Fix get_list method not returning uuid and status from JSON response
  * Log to debug instead of error where exceptions are already raised.
  * Add raw server response to debug log messages.
  * Update docstrings



  * **New API method:** `retrieve_new_access_token` retrieves a new access token and updates authorization headers. Time till expiration of the access token is stored in the property `expires_in` . ([tr4nt0r](https://github.com/tr4nt0r))
  * All API methods that require authentication now raise `BringAuthException` for 401 Unauthorized status ([tr4nt0r](https://github.com/tr4nt0r))



  * **Pytest unit testing:** added pytest with full code coverage ([tr4nt0r](https://github.com/tr4nt0r))
  * **Github workflow for pytest:** added workflow for running pytests with Python 3.11 & 3.12 on Ubuntu, Windows and macOS ([tr4nt0r](https://github.com/tr4nt0r))
  * Update Python requirement to >=3.11
  * Change from implicit to explicit string conversion of `BringItemOperation` in JSON request payload ([tr4nt0r](https://github.com/tr4nt0r))
  * Change Type of `BringItemOperation` to `StrEnum` ([tr4nt0r](https://github.com/tr4nt0r))
  * `BringItem::operation` now also accepts string literals `TO_PURCHASE`, `TO_RECENTLY` & `REMOVE` ([tr4nt0r](https://github.com/tr4nt0r))
  * fix wrong variable name in `BringSyncCurrentUserResponse` class and add additional variables from JSON response ([tr4nt0r](https://github.com/tr4nt0r))
  * Improve exceptions for `save/update/remove/complete_item` and `batch_update_list` methods ([tr4nt0r](https://github.com/tr4nt0r))
  * Fix bug in `get_all_item_details` method ([tr4nt0r](https://github.com/tr4nt0r))
  * Parsing error when parsing unauthorized response now raises `BringParseException` ([tr4nt0r](https://github.com/tr4nt0r))
  * Cleanup legacy code ([tr4nt0r](https://github.com/tr4nt0r))



  * **map user language to locales**: Bring sometimes stores non-standard locales in the user settings. In case the Bring API returns an invalid/unsupported locale, the user language is now mapped to a supported locale.



  * fix incorrect filtering of locales against supported locales list



  * Fix KeyError when listArticleLanguage is not set.



  * Load article translations from file in executor instead of event loop.



  * Improve mypy type checking.



  * Fixed build script to add locales explicitly.



  * Add article translation tables to package. Translation tables are now loaded from file as data from web app is outdated.



  * **New API method:** `batch_update_list`. Uses the same API endpoint as the mobile app to add, complete and remove items from shopping lists and has support for uuid as unique identifier for list items.
  * `save_item`, `update_item`, `complete_item` and `remove_item` are now wrapper methods for `batch_update_list` and have the additional parameter item_uuid.



  * instead of downloading all translation tables, required locales are determined from the user list settings and the user locale. ([tr4nt0r](https://github.com/tr4nt0r))
  * variable `userlistsettings` renamed to snake_cae `user_list_settings`. ([tr4nt0r](https://github.com/tr4nt0r))



  * **Localization support:** catalog items are now automatically translated based on the shopping lists language if configured, otherwise the users default language is used ([tr4nt0r](https://github.com/tr4nt0r))
  * **New API method:** `get_user_account`. Retrieves information about the current user like email, name and language ([tr4nt0r](https://github.com/tr4nt0r))
  * **New API method:** `get_all_user_settings`. Retrieves user settings like default list and individual list settings for section order and language ([tr4nt0r](https://github.com/tr4nt0r))



  * Unpin requirements and remove subdependencies ([tr4nt0r](https://github.com/tr4nt0r))



  * Refactor for PEP8 compliance and code clean-up (breaking change) ([tr4nt0r](https://github.com/tr4nt0r))



  * Add new method does_user_exist ([tr4nt0r](https://github.com/tr4nt0r))
  * Fixes for test workflow



  Add test workflow.



  Add mypy for type-checking.



  Add ruff as formatter and linter.



  Change name of package to `bring-api`.



  Test publish workflow for pypi, no code related changes.



  Initial commit based on `3.0.0` from [eliasball](https://github.com/eliasball/python-bring-api).


pkgId: 6580c098c29b71be0dae174242f82988d1d32cce8b613b03ee88ccd271e524b6
name: python-bring-api
arch: src
version: 0.9.1
epoch: 0
release: 1
summary: Unofficial package to access Bring! shopping lists API.
url: https://pypi.org/project/bring-api/
rpm_license: MIT License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-bring-api-0.9.1-1.src.rpm
checksum_type: sha256
description:
  [![PyPI version](https://badge.fury.io/py/bring-api.svg)](https://pypi.org/p/bring-api)
  [![Pytest](https://github.com/miaucl/bring-api/actions/workflows/pytest.yaml/badge.svg)](https://github.com/miaucl/bring-api/actions/workflows/pytest.yaml)
  [![Ruff](https://github.com/miaucl/bring-api/actions/workflows/ruff.yml/badge.svg)](https://github.com/miaucl/bring-api/actions/workflows/ruff.yml)
  [![Mypy](https://github.com/miaucl/bring-api/actions/workflows/mypy.yaml/badge.svg)](https://github.com/miaucl/bring-api/actions/workflows/mypy.yaml)
  [![Markdownlint](https://github.com/miaucl/bring-api/actions/workflows/markdownlint.yml/badge.svg)](https://github.com/miaucl/bring-api/actions/workflows/markdownlint.yml)
  [![Docs](https://github.com/miaucl/bring-api/actions/workflows/documentation.yml/badge.svg)](https://github.com/miaucl/bring-api/actions/workflows/documentation.yml)
  [![Integration test](https://github.com/miaucl/bring-api/actions/workflows/test.yaml/badge.svg)](https://github.com/miaucl/bring-api/actions/workflows/test.yaml)

  An unofficial python package to access the Bring! shopping lists API.

  [![Sponsor](https://img.shields.io/badge/sponsor-30363D?style=for-the-badge&logo=GitHub-Sponsors&logoColor=#EA4AAA)](https://github.com/sponsors/miaucl)
  [![BuyMeACoffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://buymeacoffee.com/miaucl)
  [@miaucl](https://github.com/@miaucl)

  [![Sponsor](https://img.shields.io/badge/sponsor-30363D?style=for-the-badge&logo=GitHub-Sponsors&logoColor=#EA4AAA)](https://github.com/sponsors/tr4nt0r)
  [![BuyMeACoffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://buymeacoffee.com/tr4nt0r)
  [@tr4nt0r](https://github.com/@tr4nt0r)



  > This implementation of the api is derived from the generic python implementation by [eliasball](https://github.com/eliasball/python-bring-api), which uses the legacy version of the api. This fork has been synced last time on 2024-02-11 and diverges from that point on using the non-legacy version. The implementation of [eliasball](https://github.com/eliasball/python-bring-api) is a **minimal** python port of the [node-bring-api](https://github.com/foxriver76/node-bring-api) by [foxriver76](https://github.com/foxriver76). All credit goes to him for making this awesome API possible!



  The developers of this module are in no way endorsed by or affiliated with Bring! Labs AG, or any associated subsidiaries, logos or trademarks.



  As python package from [PyPI](https://pypi.org/p/bring-api)

  `pip install bring-api`

  Available as integration in [Home Assistant](https://www.home-assistant.io/integrations/bring/)

  [![Open your Home Assistant instance and start setting up a new integration.](https://my.home-assistant.io/badges/config_flow_start.svg)](https://my.home-assistant.io/redirect/config_flow_start/?domain=bring)



  See below for usage examples. See [Exceptions](#exceptions) for API-specific exceptions and mitigation strategies for common exceptions.



  The API is based on the async HTTP library `aiohttp`.

  ```python
  import aiohttp
  import asyncio
  import logging
  import sys

  from bring_api import Bring

  logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

  async def main():
    async with aiohttp.ClientSession() as session:
      
      bring = Bring(session, "MAIL", "PASSWORD")
      
      await bring.login()

      
      lists = (await bring.load_lists())["lists"]

      
      await bring.save_item(lists[0]['listUuid'], 'Milk', 'low fat')

      
      await bring.save_item(lists[0]['listUuid'], 'Carrots')

      
      items = await bring.get_list(lists[0]['listUuid'])
      print(items)

      
      await bring.complete_item(lists[0]['listUuid'], 'Carrots')

      
      await bring.remove_item(lists[0]['listUuid'], 'Milk')

  asyncio.run(main())
  ```



  This method uses the newer API endpoint for adding, completing and removing items from a list, which is also used in the Bring App. The items can be identified by their uuid and therefore some things are possible that are not possible with the legacy endpoints like:

  - Add/complete/remove multiple items at once
  - Adding multiple items with the same Name but different specifications
  - You can work with a unique identifier for an item even before adding it to a list, just use uuid4 to generate a random uuid!

  Usage examples:



  When adding an item, the `itemId` is required, `spec` and `uuid` are optional. If you need a unique identifier before adding an item, you can just generate a uuid4.

  ```python
  item = {
    "itemId": "Cilantro",
    "spec": "fresh",
    "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
  }
  await bring.batch_update_list(
    lists[0]['listUuid'],
    item,
    BringItemOperation.ADD)
  ```



  When updating an item, use ADD operation again. The `itemId` is required and the item `spec` will be added/updated on the existing item on the list. For better matching an existing item (if there is more than one item with the same `itemId`), you can use it's unique identifier `uuid`.

  ```python
  item = {
    "itemId": "Cilantro",
    "spec": "dried",
    "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
  }
  await bring.batch_update_list(
    lists[0]['listUuid'],
    item,
    BringItemOperation.ADD)
  ```



  ```python

  items = [{
    "itemId": "Cilantro",
    "spec": "fresh",
    "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
  },
  {
    "itemId": "Parsley",
    "spec": "dried",
    "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
  }]
  await bring.batch_update_list(
    lists[0]['listUuid'],
    items,
    BringItemOperation.ADD)
  ```



  When adding items with the same name the parameter `uuid` is required, otherwise the previous item will be matched by `itemId` and it's specification will be overwritten

  ```python
  items = [
    {
      "itemId": "Cilantro",
      "spec": "100g, dried",
      "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
    },
      {
      "itemId": "Cilantro",
      "spec": "fresh",
      "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
    }
  ]
  await bring.batch_update_list(
    lists[0]['listUuid'],
    items,
    BringItemOperation.ADD)
  ```



  When removing or completing an item you must submit `itemId` and `uuid`, `spec` is optional. Only the `uuid` will not work. Leaving out the `uuid` and submitting `itemId` and `spec` will also work. When submitting only `itemId` the Bring API will match the oldest item.

  ```python
  await bring.batch_update_list(
    lists[0]['listUuid'],
    {"itemId": "Cilantro", "uuid" : "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"},
    BringItemOperation.REMOVE)

  await bring.batch_update_list(
    lists[0]['listUuid'],
    {"itemId": "Cilantro", "uuid" : "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"},
    BringItemOperation.COMPLETE)
  ```



  An item that is already on the list can be renamed by sending it's `uuid` with a changed `itemId`. But it is highly advised against it because the Bring App will behave weirdly as it does not refresh an items name, not even when force reloading (going to the top of the list and pulling down). Users have to close the list by going to the overview or closing the app and only then when the list is completely refreshed the change of the name will show up.

  ```python

  item = {
    "itemId": "Cilantro",
    "uuid" : "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
  }
  await bring.batch_update_list(
    lists[0]['listUuid'],
    item,
    BringItemOperation.ADD)


  item["itemId"] = "Coriander"
  await bring.batch_update_list(
    lists[0]['listUuid'],
    item,
    BringItemOperation.ADD)
  ```



  In case something goes wrong during a request, several exceptions can be thrown.
  They will either be BringRequestException, BringParseException, or BringAuthException, depending on the context. All inherit from BringException.



  With the async calls, you might encounter an error that another asyncio event loop is already running on the same thread. This is expected behavior according to the asyncio.run() [documentation](https://docs.python.org/3/library/asyncio-runner.html#asyncio.run). You cannot use more than one aiohttp session per thread, reuse the existing one!



  Due to a known issue in some versions of aiohttp when using Windows, you might encounter a similar error to this:

  ```python
  Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x00000000>
  Traceback (most recent call last):
    File "C:\...\py38\lib\asyncio\proactor_events.py", line 116, in __del__
      self.close()
    File "C:\...\py38\lib\asyncio\proactor_events.py", line 108, in close
      self._loop.call_soon(self._call_connection_lost, None)
    File "C:\...\py38\lib\asyncio\base_events.py", line 719, in call_soon
      self._check_closed()
    File "C:\...\py38\lib\asyncio\base_events.py", line 508, in _check_closed
      raise RuntimeError('Event loop is closed')
  RuntimeError: Event loop is closed
  ```

  You can fix this according to [this](https://stackoverflow.com/questions/68123296/asyncio-throws-runtime-error-with-exception-ignored) stackoverflow answer by adding the following line of code before executing the library:

  ```python
  asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
  ```



  Setup the dev environment using VSCode, is is highly recommended.

  ```bash
  python -m venv .venv
  source .venv/bin/activate
  pip install -r requirements_dev.txt
  ```

  Install [pre-commit](https://pre-commit.com)

  ```bash
  pre-commit install


  pre-commit run --all-files
  ```

  Following VSCode integrations may be helpful:

  - [ruff](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff)
  - [mypy](https://marketplace.visualstudio.com/items?itemName=matangover.mypy)
  - [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint)



  It is only possible to release a _final version_ on the `main` branch. For it to pass the gates of the `publish` workflow, it must have the same version in the `tag`, the `bring_api/__init__.py` and an entry in the `CHANGELOG.md` file.

  To release a prerelease version, no changelog entry is required, but it can only happen on a feature branch (**not** `main` branch). Also, prerelease versions are marked as such in the github release page.





  - Don't raise BringParseException on parsing errors for unauthorized request responses



  - Add type hints for item attributes (purchase conditions)
  - Minor code quality improvements, fix typos and upgrade type annotations



  - Reload locales after setting list language to ensure all required article translations are available



  - **New API method:** `set_list_article_language` sets the article language for a specified shopping list.



  - Change `name` and `photoPath` in type definitions for `BringSyncCurrentUserResponse` and `BringAuthResponse` to optional parameters
  - Add py.typed file so that type checkers can use type annotations



  - fix bug in debug log message.



  - Fix get_list method not returning uuid and status from JSON response
  - Log to debug instead of error where exceptions are already raised.
  - Add raw server response to debug log messages.
  - Update docstrings



  - **New API method:** `retrieve_new_access_token` retrieves a new access token and updates authorization headers. Time till expiration of the access token is stored in the property `expires_in` . ([tr4nt0r](https://github.com/tr4nt0r))
  - All API methods that require authentication now raise `BringAuthException` for 401 Unauthorized status ([tr4nt0r](https://github.com/tr4nt0r))



  - **Pytest unit testing:** added pytest with full code coverage ([tr4nt0r](https://github.com/tr4nt0r))
  - **Github workflow for pytest:** added workflow for running pytests with Python 3.11 & 3.12 on Ubuntu, Windows and macOS ([tr4nt0r](https://github.com/tr4nt0r))
  - Update Python requirement to >=3.11
  - Change from implicit to explicit string conversion of `BringItemOperation` in JSON request payload ([tr4nt0r](https://github.com/tr4nt0r))
  - Change Type of `BringItemOperation` to `StrEnum` ([tr4nt0r](https://github.com/tr4nt0r))
  - `BringItem::operation` now also accepts string literals `TO_PURCHASE`, `TO_RECENTLY` & `REMOVE` ([tr4nt0r](https://github.com/tr4nt0r))
  - fix wrong variable name in `BringSyncCurrentUserResponse` class and add additional variables from JSON response ([tr4nt0r](https://github.com/tr4nt0r))
  - Improve exceptions for `save/update/remove/complete_item` and `batch_update_list` methods ([tr4nt0r](https://github.com/tr4nt0r))
  - Fix bug in `get_all_item_details` method ([tr4nt0r](https://github.com/tr4nt0r))
  - Parsing error when parsing unauthorized response now raises `BringParseException` ([tr4nt0r](https://github.com/tr4nt0r))
  - Cleanup legacy code ([tr4nt0r](https://github.com/tr4nt0r))



  - **map user language to locales**: Bring sometimes stores non-standard locales in the user settings. In case the Bring API returns an invalid/unsupported locale, the user language is now mapped to a supported locale.



  - fix incorrect filtering of locales against supported locales list



  - Fix KeyError when listArticleLanguage is not set.



  - Load article translations from file in executor instead of event loop.



  - Improve mypy type checking.



  - Fixed build script to add locales explicitly.



  - Add article translation tables to package. Translation tables are now loaded from file as data from web app is outdated.



  - **New API method:** `batch_update_list`. Uses the same API endpoint as the mobile app to add, complete and remove items from shopping lists and has support for uuid as unique identifier for list items.
  - `save_item`, `update_item`, `complete_item` and `remove_item` are now wrapper methods for `batch_update_list` and have the additional parameter item_uuid.



  - instead of downloading all translation tables, required locales are determined from the user list settings and the user locale. ([tr4nt0r](https://github.com/tr4nt0r))
  - variable `userlistsettings` renamed to snake_cae `user_list_settings`. ([tr4nt0r](https://github.com/tr4nt0r))



  - **Localization support:** catalog items are now automatically translated based on the shopping lists language if configured, otherwise the users default language is used ([tr4nt0r](https://github.com/tr4nt0r))
  - **New API method:** `get_user_account`. Retrieves information about the current user like email, name and language ([tr4nt0r](https://github.com/tr4nt0r))
  - **New API method:** `get_all_user_settings`. Retrieves user settings like default list and individual list settings for section order and language ([tr4nt0r](https://github.com/tr4nt0r))



  - Unpin requirements and remove subdependencies ([tr4nt0r](https://github.com/tr4nt0r))



  - Refactor for PEP8 compliance and code clean-up (breaking change) ([tr4nt0r](https://github.com/tr4nt0r))



  - Add new method does_user_exist ([tr4nt0r](https://github.com/tr4nt0r))
  - Fixes for test workflow



  Add test workflow.



  Add mypy for type-checking.



  Add ruff as formatter and linter.



  Change name of package to `bring-api`.



  Test publish workflow for pypi, no code related changes.



  Initial commit based on `3.0.0` from [eliasball](https://github.com/eliasball/python-bring-api).


pkgId: 5714c98ac2a1eca37e8bd3cb96832c3f95f49d8e505b719d14f4d86025e0a372
name: python-brisk-ml
arch: src
version: 0.1.0
epoch: 0
release: 1
summary: A framework that helps train machine learning models using sklearn.
url: https://pypi.org/project/brisk-ml/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brisk-ml-0.1.0-1.src.rpm
checksum_type: sha256
description:
  A framework that helps train machine learning models using sklearn.

  The package aims to speed up the training process by providing built in methods for analysis. It also provides a strucutre to help keep code organized. The package automatically tracks the settings used during training to help with repeatability. Users can define their own methods for algorithms, metrics or evaluation and integrate them with the package methods easily.



  1. Create a new project
  - brisk create -n project_name
  - Create directory with configuration files
  - cd ./project_name

  2. settings.py
  - in TRAINING_MANAGER_CONFIG define the algorithms to use
  - Define the paths to the data files to use
  - In WORKFLOW_CONFIG add settings for model training

  3. metrics.py
  - Define the metrics to use
  - Can load defaults from brisk.REGRESSION_METRICS or brisk.CLASSIFICATION_METRICS
  - Can add custom metrics by defining a function that takes y_true and y_pred
      - Create a MetricWrapper with this function

  4. data.py
  - Define how data should be split/processed

  5. algorithms.py
  - Define the default parameters and hyperparameter space to use.
  - Can load defaults using brisk.CLASSIFICATION_ALGORITHMS or brisk.REGRESSION_ALGORITHMS

  6. Create a Workflow
  - In workflows/ directory define a Workflow class
  - you can access built in evaluation methods
  - You can define your own methods in the workflow class

  7. Run the Workflow
  - navigate to the project root (directory created by brisk create)
  - brisk run -w workflow_file
  - This will run the workflow defined by the workflow class in this file

  8. Analyze Results
  - results are stored in the results directory
  - When complete an HTML report is generated
  - Analysis of the data splits is run automatically
  - A log file with the settings used is created
  - All the built in evaluation methods export their results to a file by default


pkgId: 4b5a12a5cfeea0f517b2468118ea83105e7e24825ff4af40c366afd8dcb39c46
name: python-britishcycling-clubs
arch: src
version: 0.11.0
epoch: 0
release: 1
url: https://github.com/elliot-100/britishcycling-clubs
rpm_license: GPL-3.0-only
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-britishcycling-clubs-0.11.0-1.src.rpm
checksum_type: sha256
summary:
  Unofficial library to automate aspects of British/Scottish/Welsh Cycling's club Membership Manager system

description:
  **Unofficial, not affiliated or endorsed by British/Scottish/Welsh Cycling.**

  Library to automate aspects of British Cycling's Club Management Tool, in order to
  simplify administration for clubs using it. It probably works for Scottish/Welsh
  Cycling clubs too, but this hasn't been tested.

  Priority is to read data in order to create reports/notifications to club
  administrators.




  - ID for a club
  - for Club Management Tool functions, valid user credentials




  Install from PyPI, e.g:
  ```shell
  pip install britishcycling-clubs
  ```

  Some functions use [Playwright](https://playwright.dev/python/) to automate a headless Chromium browser. This needs
  to be installed separately before first use, and after most Playwright updates, e.g.:
  ```shell
  playwright install chromium
  ```

  If you're installing in e.g. a bare-bones server/CI environment, you'll probably be
  prompted to install system dependencies, which you can do with e.g.:
  ```shell
  playwright install-deps chromium
  ```

  See also https://playwright.dev/python/docs/browsers#install-system-dependencies






  ```python
  from britishcycling_clubs import get_profile_info
  get_profile_info(club_id="123")
  ```
  Returns an instance of `ProfileInfo`, a `NamedTuple` with attributes:

  - `club_name`: Club name [str]
  - `total_members`: Total club members [int]

  Example script `example_profile_info.py` loads club ID from `config.ini` (you'll
  need to copy `config_dist.ini`, populate club ID only and rename).
  It then retrieves and prints the club name and total member count.




  ```python
  from britishcycling_clubs import profile_url
  profile_url(club_id="123")
  ```



  ```python
  from britishcycling_clubs import get_manager_member_counts
  get_manager_member_counts(
      club_id="123",
      username="USERNAME",
      password="PASSWORD",
      manager_page_load_delay=7,
  )
  ```
  Returns an instance of `ManagerMemberCounts`, a `NamedTuple` with attributes:

  - `active`: count of 'Active Club Members' [int]
  - `expired`: count of 'Expired Club Members' [int]
  - `new`: count of 'New Club Subscriptions' i.e. pending members [int]

  This takes about 10 s.

  Example script `example_manager_member_counts.py` loads club ID and credentials from
  `config.ini` (you'll need to copy `config_dist.ini`, populate and rename to
  `config.ini`).
  It then retrieves and prints the number of active, expired and new
  club member counts from the club's Club Manager pages.



  ```python
  from britishcycling_clubs import manager_url_via_login
  manager_url_via_login(club_id="123")
  ```
  Returns URL which redirects to Club Manager URL, via login if needed.


pkgId: 518ccd185b2f4a1b49c9f9827734ff44cd915b57376fc2d761288b500c7add32
name: python-britive
arch: src
version: 3.1.0
epoch: 0
release: 1
summary: A pure Python SDK for the Britive API
url: https://www.britive.com
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-britive-3.1.0-1.src.rpm
checksum_type: sha256
description:
  Pure Python implementation for interacting with the [Britive API](https://docs.britive.com/v1/docs/en/overview-britive-apis).

  This package aims to wrap the Britive API for usage in Python development. For the most part it is a simple wrapper
  (sending potentially bad parameters to the API) but there are a couple of places where liberties were taken to enhance
  the developer/end user experience. Some APIs may also be combined into one Python method with a parameter if and where
  it makes more sense to present the API that way.

  This package supports Python versions `>= 3.8`.



  ```sh
  pip install britive
  ```

  Or execute one of the following commands if you wish to pull directly from the Github repo instead of PyPi. Or navigate
  to Releases and use the URL of the tarball release that is needed, if not the lastest.

  ```sh
  pip install $(curl -s https://api.github.com/repos/britive/python-sdk/releases/latest \
      | jq -r '.assets[] | select(.content_type == "application/x-gzip") | .browser_download_url')

  OR

  pip install $(curl -s https://api.github.com/repos/britive/python-sdk/releases/latest \
      | grep "browser_download_url.*.tar.gz" | cut -d : -f 2,3 | tr -d \")
  ```



  Each public method is documented with a docstring which provides details on what the method does, the parameters the
  method accepts, and details about what is returned from the method.

  Official API documentation can be found here: [Overview of Britive APIs](https://docs.britive.com/v1/docs/en/overview-britive-apis).



  Authentication is handled solely via API tokens. The token must be provided in one of two methods.

  1. Passed directly into the class constructor.
  2. Injected as an environment variable into the execution context where this package is being run.
      1. The environment variable name must be `BRITIVE_API_TOKEN`.

  > _As of `v2.5.0` a `Bearer` token can be provided as well._
  > _A `Bearer` token is generated as part of an interactive login process and is temporary in nature._
  > _This is to support the [Britive Python CLI](https://github.com/britive/python-cli/)._

  All Britive API tokens are authenticated against a specific Britive tenant. The name of the tenant must be presented in
  one of two methods.

  1. Passed directly into the `Britive` class constructor.
  2. Injected as an environment variable into the execution context where this package is being run.
      1. The environment variable name must be `BRITIVE_TENANT`.

  > _In order to obtain the tenant name, reference the Britive URL used to log into the UI._
  > _If the URL is `https://example.britive-app.com` then the tenant name will be `example`._



  All pagination is handled by the package. The caller will never have to deal with paginated responses.



  * The caller has access to an active Britive tenant.
  * The caller has been granted an API token and/or has the ability to generate an API token.
    * This can be either for a _User_ or _Service Identity_.
  * No assumptions are made about the operating system or file system.
    * Nothing is persisted to disk.
      * The end user must persist responses to disk if and when that is required.



  The following Britive resources are supported with full CRUDL operations where appropriate, and additional actions where
  they exist.

  * Access Broker
  * Access Builder
  * Accounts
  * Accounts (associated with an application/environment)
  * API Tokens (for Users)
  * Applications
  * Audit Logs
  * Environment
  * Environment Groups
  * Groups (associated with an application/environment)
  * Identity Attributes
  * Identity Providers
  * My Access (access granted to the given identity (user or service))
  * My Resources (access granted to the given identity (user or service))
  * My Secrets (access granted to the given identity (user or service))
  * Notifications
  * Permissions (associated with an application/environment)
  * Profiles
  * Reports
  * SAML Settings
  * Scans
  * Security Policies
  * Service Identities
  * Service Identity Tokens
  * System Announcement (aka banner)
  * Tags (aka User Tags)
  * Task Services
  * Tasks
  * Users



  Under the covers, python [`requests`](https://github.com/psf/requests) is being used to communicate with the Britive API.
  As such, any functionality of `requests` can be used, including setting an HTTP proxy.

  * HTTP proxies will be set via environment variables.
    * `HTTP_PROXY`
    * `HTTPS_PROXY`
    * `NO_PROXY`
    * `http_proxy`
    * `https_proxy`
    * `no_proxy`

  > _Standard HTTP proxy URLs should be utilized._
  >
  > _Examples:_
  >
  > * _Unauthenticated Proxy: `http://internalproxy.domain.com:8080`_
  > * _Authenticated Proxy: `http://user:pass@internalproxy.domain.com:8080`_



  Setting custom TLS certificates functionality of `requests` can also be used.

  * Certificate bundles can be set via environment variables.
    * `REQUESTS_CA_BUNDLE`
    * `CURL_CA_BUNDLE` _(used as a fallback)_
    * `PYBRITIVE_CA_BUNDLE` _(specific to the Britive Python SDK)_

  > _The values of these environment variables must be a path to a directory of certificates or a specific certificate._
  >
  > _Example:_
  > _`/path/to/certfile`_





  ```sh
  export REQUESTS_CA_BUNDLE="/usr/local/corp-proxy/cacert.pem"
  ```



  __powershell:__

  ```pwsh
  $env:REQUESTS_CA_BUNDLE = "C:\Users\User\AppData\Local\corp-proxy\cacert.pem"
  ```

  __cmd:__

  ```bat
  set REQUESTS_CA_BUNDLE="C:\Users\User\AppData\Local\corp-proxy\cacert.pem"
  ```





  This should be the only class that is required for import.

  ```python
  from britive.britive import Britive
  ```

  Optionally, the various exceptions that this package raises can be imported as well, e.g.

  ```python
  from britive import exceptions
  ```

  Then specific exception(s) could be referenced as demonstrated below:

  ```python
  try:
      something()
  except exceptions.TokenMissingError():
      handle()
  ```



  ```python
  from britive.britive import Britive
  import json

  britive = Britive()  # source needed data from environment variables

  print(json.dumps(britive.users.list(), indent=2, default=str))
  ```



  ```python
  from britive.britive import Britive
  import json

  britive = Britive(tenant='example', token='...') # source token and tenant locally (not from environment variables)

  print(json.dumps(britive.users.list(), indent=2, default=str))
  ```



  ```python
  from britive.britive import Britive
  import json

  britive = Britive()  # source needed data from environment variables

  print(json.dumps(britive.service_identity_tokens.create(service_identity_id='abc123'), indent=2, default=str))
  ```



  ```python
  from britive.britive import Britive
  import json

  britive = Britive()  # source needed data from environment variables

  print(json.dumps(britive.reports.run(report_id='abc123'), indent=2, default=str))

  with open('file.csv', 'w') as f:
      f.write(britive.reports.run(report_id='abc123', csv=True))
  ```



  The commands below will create a policy on a profile that allows `user@domain.com` to check out the profile but only if
  `approver@domain.com` approves that request within 10 minutes.

  ```python
  from britive.britive import Britive

  b = Britive()

  policy = b.profiles.policies.build(
      name='example',
      users=['user@domain.com'],
      approval_notification_medium='Email',
      approver_users=['approver@domain.com'],
      time_to_approve=10
  )

  b.profiles.policies.create(profile_id='...', policy=policy)
  ```

rpm_license:
  MIT License  Copyright (c) 2022 Britive, Inc  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: 51e377fae571d405ee81053b427a0962307cb3f1d7987d6fe911b9c17bfbd1dd
name: python-briton
arch: src
version: 0.3.10
epoch: 0
release: 1
summary: Python component of using Briton
url: https://pypi.org/project/briton/
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-briton-0.3.10-1.src.rpm
checksum_type: sha256
description:
  The python side of Briton. Briton server is written in C++ for high performance
  and provides a grpc endpoint for interaction. A major function of this python
  libarary is to provide easier interaction with the Briton Server. e.g. there's
  logic to startup the Briton server and ensure it's healthy. It also provides
  adapters for using Briton from Truss. For certain features, such as draft model
  based speculative decoding, a subtantial chunk of the implementation is in this
  library.


pkgId: ecc21e10ab5f78a39eb9f046ce94e908f737e1fd013df309754f1415fccfca85
name: python-bro
arch: src
version: 0.2.11
epoch: 0
release: 1
summary: Open source python library for accessing BRO API
url: https://pypi.org/project/bro/
rpm_license: see LICENSE.txt
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-bro-0.2.11-1.src.rpm
checksum_type: sha256
description:
  ![](https://img.shields.io/badge/release-v0.2.11-green)


  This package can access the REST API from the [BRO](https://www.broloket.nl/ondergrondgegevens). Currently, this package provides
  functionality to request CPTs from the BRO when you provide a region of interest. The format is based on the REST API of the BRO, which is described [here](https://publiek.broservices.nl/sr/cpt/v1/swagger-ui/#/default/) for CPTs.

  Current options include retrieval of the following objects:
  1. CPTs (format: bytes, dict)

  The package also allows export of the retrieved data in GeoJSON format.

  **Note 1**: The BRO is only available for the Netherlands, other locations are not supported.

  **Note 2**: The API of the BRO is limited and requesting large amounts of data may result in instability.



  ```python
  pip install bro
  ```


  Example usage to retrieve CPTs from the BRO as dictionaries.
  ```python
  from datetime import datetime

  import Envelope
  import Point
  import get_cpt_characteristics_and_return_cpt_objects

  begin_date = datetime(2015, 1, 1).strftime("%Y-%m-%d")
  end_date = datetime(2023, 3, 3).strftime("%Y-%m-%d")


  lower_corner = Point(51.92269686635185, 4.469594207611851)
  upper_corner = Point(51.923034432171065, 4.470094707426648)

  area = Envelope(lower_corner, upper_corner)
  cpts = get_cpt_characteristics_and_return_cpt_objects(begin_date, end_date, area, as_dict= True)


  ```



  ```
  MIT License

  Copyright (c) 2023 VIKTOR

  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.

  ```


  - update changelog with version number
  - update `bro/__version__.py`
  - tag with version number


pkgId: 91b4f1870eacd7fa57da0d80764868c84e86f86ccb2b58694c96fea46067b49f
name: python-broadcaster
arch: src
version: 0.3.1
epoch: 0
release: 1
summary: Simple broadcast channels.
url: https://github.com/encode/broadcaster
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-broadcaster-0.3.1-1.src.rpm
checksum_type: sha256
description:
  Broadcaster helps you develop realtime streaming functionality by providing
  a simple broadcast API onto a number of different backend services.

  It currently supports [Redis PUB/SUB](https://redis.io/topics/pubsub), [Redis Streams](https://redis.io/docs/latest/develop/data-types/streams/), [Apache Kafka](https://kafka.apache.org/), and [Postgres LISTEN/NOTIFY](https://www.postgresql.org/docs/current/sql-notify.html), plus a simple in-memory backend, that you can use for local development or during testing.

  <img src="https://raw.githubusercontent.com/encode/broadcaster/master/docs/demo.gif" alt='WebSockets Demo'>

  Here's a complete example of the backend code for a simple websocket chat app:

  **app.py**

  ```python


  import anyio
  from broadcaster import Broadcast
  from starlette.applications import Starlette
  from starlette.routing import Route, WebSocketRoute
  from starlette.templating import Jinja2Templates


  broadcast = Broadcast("redis://localhost:6379")
  templates = Jinja2Templates("templates")


  async def homepage(request):
      template = "index.html"
      context = {"request": request}
      return templates.TemplateResponse(template, context)


  async def chatroom_ws(websocket):
      await websocket.accept()

      async with anyio.create_task_group() as task_group:
          
          async def run_chatroom_ws_receiver() -> None:
              await chatroom_ws_receiver(websocket=websocket)
              task_group.cancel_scope.cancel()

          task_group.start_soon(run_chatroom_ws_receiver)
          await chatroom_ws_sender(websocket)


  async def chatroom_ws_receiver(websocket):
      async for message in websocket.iter_text():
          await broadcast.publish(channel="chatroom", message=message)


  async def chatroom_ws_sender(websocket):
      async with broadcast.subscribe(channel="chatroom") as subscriber:
          async for event in subscriber:
              await websocket.send_text(event.message)


  routes = [
      Route("/", homepage),
      WebSocketRoute("/", chatroom_ws, name='chatroom_ws'),
  ]


  app = Starlette(
      routes=routes, on_startup=[broadcast.connect], on_shutdown=[broadcast.disconnect],
  )
  ```

  The HTML template for the front end [is available here](https://github.com/encode/broadcaster/blob/master/example/templates/index.html), and is adapted from [Pieter Noordhuis's PUB/SUB demo](https://gist.github.com/pietern/348262).



  Python 3.8+



  * `pip install broadcaster`
  * `pip install broadcaster[redis]`
  * `pip install broadcaster[postgres]`
  * `pip install broadcaster[kafka]`



  * `Broadcast('memory://')`
  * `Broadcast("redis://localhost:6379")`
  * `Broadcast("redis-stream://localhost:6379")`
  * `Broadcast("postgres://localhost:5432/broadcaster")`
  * `Broadcast("kafka://localhost:9092")`




  You can create your own backend and use it with `broadcaster`.
  To do that you need to create a class which extends from `BroadcastBackend`
  and pass it to the `broadcaster` via `backend` argument.

  ```python
  from broadcaster import Broadcaster, BroadcastBackend

  class MyBackend(BroadcastBackend):

  broadcaster = Broadcaster(backend=MyBackend())
  ```



  At the moment `broadcaster` is in Alpha, and should be considered a working design document.

  The API should be considered subject to change. If you *do* want to use Broadcaster in its current
  state, make sure to strictly pin your requirements to `broadcaster==0.3.0`.

  To be more capable we'd really want to add some additional backends, provide API support for reading recent event history from persistent stores, and provide a serialization/deserialization API...

  * Serialization / deserialization to support broadcasting structured data.
  * A backend for RabbitMQ.
  * Add support for `subscribe('chatroom', history=100)` for backends which provide persistence. (Redis Streams, Apache Kafka) This will allow applications to subscribe to channel updates, while also being given an initial window onto the most recent events. We *might* also want to support some basic paging operations, to allow applications to scan back in the event history.
  * Support for pattern subscribes in backends that support it.




  [Gist](https://gist.github.com/alex-oleshkevich/68411a0e7ad24d53afd28c3fa5da468c)

  Integrates MQTT with Broadcaster


pkgId: 42cc04df13ae2bae9e34d5a3dacd19f4fcb34509b6d6dbecc0cfb88bf240e029
name: python-broadworks-ocip
arch: src
version: 2.2.0
epoch: 0
release: 1
summary: API interface to the OCI-P provisioning interface of a Broadworks softswitch
url: https://pypi.org/project/broadworks-ocip/
rpm_license: BSD
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-broadworks-ocip-2.2.0-1.src.rpm
checksum_type: sha256
description:
  -   python objects to match all Broadworks schema objects
  -   API framework to talk to a Broadworks server
  -   additional magic to handle authentication and sessions
  -   Based on Broadworks schema R25

  Version: `2.2.0`


pkgId: 63ac45250f392de15036fd362464ce606a819f70e9fc53dc9d421a035ca5f872
name: python-brokenaxes
arch: src
version: 0.6.2
epoch: 0
release: 1
summary: Create broken axes
url: https://github.com/bendichter/brokenaxes
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brokenaxes-0.6.2-1.src.rpm
checksum_type: sha256
description:
  ![brokenaxes logo. Reference: http://www.brianhensley.net/2012/02/python-controlling-spi-bus-on.html](https://raw.githubusercontent.com/bendichter/brokenaxes/master/broken_python_snake.png)

  brokenaxes makes matplotlib plots with breaks in the axes for showing data across a discontinuous range.

  [![PyPI](https://img.shields.io/pypi/v/brokenaxes.svg?style=plastic)](https://pypi.python.org/pypi/brokenaxes)
  [![PyPI - Downloads](https://img.shields.io/pypi/dm/brokenaxes.svg?color=purple&label=PyPi)](https://pypistats.org/packages/brokenaxes)
  [![codecov](https://codecov.io/gh/bendichter/brokenaxes/graph/badge.svg?token=emsyOdN4YD)](https://codecov.io/gh/bendichter/brokenaxes)


  * Break x and y axes.
  * Supports multiple breaks on a single axis.
  * Automatically scales axes according to relative ranges.
  * Plot multiple lines.
  * Legend with positioning relative to entire broken axes object
  * x and y label centered to entire plot
  * Make brokenaxes object a subplot itself with `matplotlib.GridSpec.subplot_spec`.
  * xlims and ylims may be `datetime.datetime` objects
  * Supports log scales.


  I recommend the [Anaconda python distribution](http://continuum.io/downloads) and this package is available via pypi:
  ```
  pip install brokenaxes
  ```


  ```python
  import matplotlib.pyplot as plt
  from brokenaxes import brokenaxes
  import numpy as np

  fig = plt.figure(figsize=(5, 2))
  bax = brokenaxes(xlims=((0, .1), (.4, .7)), ylims=((-1, .7), (.79, 1)), hspace=.05)
  x = np.linspace(0, 1, 100)
  bax.plot(x, np.sin(10 * x), label='sin')
  bax.plot(x, np.cos(10 * x), label='cos')
  bax.legend(loc=3)
  bax.set_xlabel('time')
  bax.set_ylabel('value')
  ```
  ![example1](https://raw.githubusercontent.com/bendichter/brokenaxes/master/example1.png)



  ```python
  from brokenaxes import brokenaxes
  from matplotlib.gridspec import GridSpec
  import numpy as np

  sps1, sps2 = GridSpec(2,1)

  bax = brokenaxes(xlims=((.1, .3), (.7, .8)), subplot_spec=sps1)
  x = np.linspace(0, 1, 100)
  bax.plot(x, np.sin(x*30), ls=':', color='m')

  x = np.random.poisson(3, 1000)
  bax = brokenaxes(xlims=((0, 2.5), (3, 6)), subplot_spec=sps2)
  bax.hist(x, histtype='bar')
  ```
  ![example2](https://raw.githubusercontent.com/bendichter/brokenaxes/master/example2.png)



  ```python
  import matplotlib.pyplot as plt
  from brokenaxes import brokenaxes
  import numpy as np

  fig = plt.figure(figsize=(5, 5))
  bax = brokenaxes(
      xlims=((1, 500), (600, 10000)),
      ylims=((1, 500), (600, 10000)),
      hspace=.15,
      xscale='log',
      yscale='log',
  )

  x = np.logspace(0.0, 4, 100)
  bax.loglog(x, x, label='$y=x=10^{0}$ to $10^{4}$')

  bax.legend(loc='best')
  bax.grid(axis='both', which='major', ls='-')
  bax.grid(axis='both', which='minor', ls='--', alpha=0.4)
  bax.set_xlabel('x')
  bax.set_ylabel('y')
  plt.show()
  ```
  ![example3](https://raw.githubusercontent.com/bendichter/brokenaxes/master/example3.png)



  ```python
  import matplotlib.pyplot as plt
  from brokenaxes import brokenaxes
  import numpy as np
  import datetime

  fig = plt.figure(figsize=(5, 5))
  xx = [datetime.datetime(2020, 1, x) for x in range(1, 20)]

  yy = np.arange(1, 20)

  bax = brokenaxes(
      xlims=(
          (
              datetime.datetime(2020, 1, 1),
              datetime.datetime(2020, 1, 3),
          ),
          (
              datetime.datetime(2020, 1, 6),
              datetime.datetime(2020, 1, 20),
          )
      )
  )

  bax.plot(xx, yy)

  fig.autofmt_xdate()
  [x.remove() for x in bax.diag_handles]
  bax.draw_diags()

  import matplotlib.dates as mdates
  for ax in bax.axs:
      ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%b-%d'))
  ```

  ![datetime_example](https://raw.githubusercontent.com/bendichter/brokenaxes/master/datetime_example.png)


  ```python
  import matplotlib.pyplot as plt
  from brokenaxes import brokenaxes

  fig = plt.figure(figsize=(5, 5))
  bax = brokenaxes(
      xlims=((0, 0.1), (0.4, 0.7)), ylims=((-1, 0.7), (0.79, 1))
  )
  bax.text(0.5, 0.5, "hello")
  ```
  ![text_example](https://github.com/bendichter/brokenaxes/assets/844306/35d2026a-a9e6-49df-9bf5-199e9a43b447)


  You can customize brokenaxes outside of the supported features listed above. Brokenaxes works by creating a number of smaller axes objects, with the positions and sizes of those axes dictated by the data ranges used in the constructor. Those individual axes are stored as a list in `bax.axs`. Most customizations will require accessing those inner axes objects. (See the last two lines of [the datetime example](https://github.com/bendichter/brokenaxes#datetime)). There is also a larger invisible axes object, `bax.big_ax`, which spans the entire brokenaxes region and is used for things like x and y axis labels which span all of the smaller axes.



  If you make a plot with this tool that you are proud of, send me a png and code and I'll add it to the gallery!


  Please use this tool wisely. Any data visualization techique can be used to elucidate trends in the data, but can also be used to manipulate and mislead. The latter is particularly true for broken axes plots, so please try to use them responsibly. Other than that, this software is free to use. See the license file for details.


  brokenaxes uses `pytest-mpl` to ensure that the plots are created correctly.

  To test that the plots are created correctly, run `pytest --mpl --mpl-baseline-path test_baseline test.py` from the root directory.

  To generate new test plots, run `pytest --mpl-generate-path test_baseline test.py` from the root directory.

  If you are running the tests on a headless server, you may need to set the MPLBACKEND environment variable to Agg.


pkgId: c4959afa04a19661021664408919501c3ff082282046f7649fc8f7881c1fa503
name: python-broker
arch: src
version: 0.6.2
epoch: 0
release: 1
summary: The infrastructure middleman.
url: https://pypi.org/project/broker/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-broker-0.6.2-1.src.rpm
checksum_type: sha256
description:
  [![PythonPackage](https://github.com/SatelliteQE/broker/actions/workflows/python-publish.yml/badge.svg)](https://github.com/SatelliteQE/broker/actions/workflows/python-publish.yml)
  [![ContainerImage](https://github.com/SatelliteQE/broker/actions/workflows/update_broker_image.yml/badge.svg)](https://github.com/SatelliteQE/broker/actions/workflows/update_broker_image.yml)
  [![CodeQL](https://github.com/SatelliteQE/broker/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/SatelliteQE/broker/actions/workflows/codeql-analysis.yml)

  The infrastrucure middleman


  Broker is a tool designed to provide a common interface between one or many services that provision virtual machines or containers. It is an abstraction layer that allows you to ignore most of the implementation details and just get what you need.


  Broker's docs can be found at the wiki for this repo: https://github.com/SatelliteQE/broker/wiki


  Install cmake with `dnf install cmake`

  **Note:** We recommend using [uv](https://github.com/astral-sh/uv?tab=readme-ov-file#installation) to manage your Broker installation.

  Install Broker either as a tool with uv `uv tool install broker`

  or with pip `pip install broker`

  **Note:** If you install with pip it is recommended that you do so in a virtual environment.

  (optional) If you are using the Container provider, install the extra dependency based on your container runtime of choice with either `... install broker[podman]` or `... install broker[docker]`.

  (optional) If you are using the Beaker provider, install the extra dependency with `dnf install krb5-devel` and then `... install broker[beaker]`.

  The first time you run Broker, like with `broker --version`, it will check if you already have a `broker_settings.yaml` in the location it expects.
  If not, then it will help you get one setup and place it in the default broker directory `~/.broker/`

  If you want Broker to operate out of a different location, export a `BROKER_DIRECTORY` environment variable with the desired path.

  You can check `broker --version` at any time to verify where it is looking for its config file.


  **Checking out a VM or container**
  To checkout a single VM with arbitrary arguments:
  ```
  broker checkout --workflow test-workflow --workflow-arg1 something --workflow-arg2 else
  ```

  To checkout multiple VMs at once:
  ```
  broker checkout --workflow test-workflow --count 3
  ```

  To pass complex data structures:
  ```
  broker checkout --container-host my-image --args-file tests/data/broker_args.json --extra tests/data/args_file.yaml
  ```

  **Nicks**

  Broker allows you to define configurable nicknames for checking out vms. Just add yours to setting.yaml and call with the `--nick` option
  ```
  broker checkout --nick rhel7
  ```

  **Listing your VMs and containers**

  Broker maintains a local inventory of the VMs and containers you've checked out. You can see these with the ```inventory``` command.
  ```
  broker inventory
  ```
  To sync your inventory from a supported provider, use the `--sync` option.
  ```
  broker inventory --sync AnsibleTower
  ```
  To sync an inventory for a specific instance, use the following syntax with --sync.
  ```
  broker inventory --sync Container::<instance name>
  ```

  **Extending your VM lease time**

  Providers supporting extending a VM's lease time make that functionality available through the `extend` subcommand.
  ```
  broker extend 0
  broker extend hostname
  broker extend vmname
  broker extend --all
  ```

  **Checking in VMs and containers**

  You can also return a VM to its provider with the `checkin` command.
  Containers checked in this way will be fully deleted regardless of its status.
  You may use either the local id (`broker inventory`), the hostname, or "all" to checkin everything.
  ```
  broker checkin my.host.fqdn.com
  broker checkin 0
  broker checkin 1 3 my.host.fqdn.com
  broker checkin --all
  ```

  **Gaining information about Broker's providers**

  Broker's `providers` command allows you to gather information about what providers are avaiable as well as each providers actions. Additionally, you can find out information about different arguments for a provider's action with this command.
  ```
  broker providers --help
  broker providers AnsibleTower --help
  broker providers AnsibleTower --workflows
  broker providers AnsibleTower --workflow test-workflow
  ```

  **Run arbitrary actions**

  If a provider action doesn't result in a host creation/removal, Broker allows you to execute that action as well. There are a few output options available as well.
  When executing with the Container provider, a new container will be spun up with your command (if specified), ran, and cleaned up.
  ```
  broker execute --help
  broker execute --workflow my-awesome-workflow --additional-arg True
  broker execute -o raw --workflow my-awesome-workflow --additional-arg True --artifacts last
  ```

  **Machine processable output**

  If running in a CI or other automated environment, Broker offers the choice to store important output information in an output file. This is json-formatted data. Please be aware that any existing file with the matching path and name will be erased.
  ```
  broker --output-file output.json checkout --nick rhel7
  broker --output-file inventory.json inventory
  ```

  **Run Broker in the background**

  Certain Broker actions can be run in the background, these currently are: checkout, checkin, and execute. When running a command in this mode, it will spin up a new Broker process and no longer log to stderr. To check progress, you can still follow broker's log file.
  Note that background mode will interfere with output options for execute since it won't be able to print to stdout. Those should kept in log mode.
  ```
  broker checkout --background --nick rhel7
  broker checkin -b --all
  broker execute -b --workflow my-awesome-workflow --artifacts
  ```


  Install cmake with `dnf install cmake`

  Clone the Broker repository and install locally with  `uv pip install "broker[dev] @ ."`

  Copy the example settings file to `broker_settings.yaml` and edit it.

  To run Broker outside of its base directory, specify the directory with the `BROKER_DIRECTORY` environment variable.


pkgId: 0c3eb6eea972c80e1895072952476a85a0e26ee467d0ffa6119b815f48dc572d
name: python-brom-drake
arch: src
version: 0.2.7
epoch: 0
release: 1
summary: A set of convenient logging and testing tools for the Drake robotics toolbox.
url: https://github.com/kwesiRutledge/brom_drake-py
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brom-drake-0.2.7-1.src.rpm
checksum_type: sha256
description:
  [![codecov](https://codecov.io/gh/kwesiRutledge/brom_drake-py/graph/badge.svg?token=0TI5PV2HUD)](https://codecov.io/gh/kwesiRutledge/brom_drake-py)


  Brom is a helper library for the [Drake](https://drake.mit.edu/) robotics simulation and verification library.
  Its goal is to simplify common debugging and testing activities in Drake (for example, logging the outputs
  of systems in your block diagrams).

  Some of Brom's features:

  Feature                    |  Code | Results
  :-------------------------:|:-------------------------:|:-------------------------:
  The Diagram Watcher (the `DiagramWatcher` will log + plot all output ports of your `Diagram` automatically) |`add_watcher_and_build()`| ![Creation of Brom Directory](./promo/BromWatcher0.gif)
  The Drake-ify feature (converts your URDF file into a form that Drake can consume) | `drakeify_my_urdf()` | ![Drakeify Example](./promo/BromDrakeifyURDF0.gif)

  (More coming soon...)



  `brom_drake` is available on PyPI and installable with pip:

  ```shell
  pip install brom-drake
  ```



  You can also install the package during local development by cloning
  the repository and running the following commands from inside it:

  ```bash
  pip install -r requirements.txt
  pip install -e .
  ```



  Here are a few of the features available in `brom_drake` and how they work.



  It is recommended that you use the convenience function `add_watcher_and_build` to add a `DiagramWatcher` to your diagram.

  ```python

  from pydrake.all import (
      DiagramBuilder, Simulator,
  )


  from brom_drake.all import add_watcher_and_build


  builder = DiagramBuilder()




  watcher, diagram, diagram_context = add_watcher_and_build(builder)


  simulator = Simulator(diagram, diagram_context)
  simulator.set_target_realtime_rate(1.0)
  simulator.set_publish_every_time_step(False)


  simulator.Initialize()
  simulator.AdvanceTo(15.0)

  ```


  What will happen whenever you use this function is that:
  - The `DiagramWatcher` will be created.
    - It will search through all systems that the `DiagramBuilder` has added.
    - For each system, the watcher will add a `VectorLogger` to each output port that is a `kVectorValued` port.
    - The `DiagramWatcher` will connect all loggers to all targeted ports (in the above case, we will target all available output ports).
  - After the simulation is run and the script completes, the watcher will save all data traces for each port in `.png` files. These plots will be in a new `.brom` directory.



  If you only want to watch a specific system, then you can do so by passing in information to the "targets" argument:
  ```python
  watcher, _, _ = add_watcher_and_build(
    builder,
    targets=[
      ("system_name", "port_name"),
      "system_name2",
    ],
  )
  ```
  The above code tells the watcher to watch the port named `port_name` on the system named `system_name`.
  (If you don't know your system's name in Drake, then you can usually find it by using the `get_name()` method.)





  [Brom the storyteller](https://inheritance.fandom.com/wiki/Brom) is a character from the
  [Inheritance](https://en.wikipedia.org/wiki/Eragon) series by Christopher Paolini.
  He is a wise mentor that helps Eragon (the protagonist) master dragons. ;)





  Some other work in the open-source drake community:
  - [kinova_drake](https://github.com/vincekurtz/kinova_drake) - A Drake-based library that builds a
    simple version of the manipulation station for the Kinova Gen3 robot arm.
    Also works with the hardware.
  - [airo-drake](https://github.com/airo-ugent/airo-drake) - A python package meant to simplify
    working with Drake and the `airo-mono` repository from the AI and Robotics Lab at Ghent University.



  - [ ] Figure out how to tell if two systems are connected in Drake.
  - [ ] Add support for abstract output ports?
  - [ ] Add more readme explanations of what is going on under the hood.
  - [ ] Add Documentation
  - [ ] Create a method that makes each material in a URDF file have unique names if they have specific values
  - [ ] Add methods for saving the state names on state plots from diagram watcher
  - [ ] Add methods for over or under-approximating complex mehes with cylinders or circles or other shapes.


pkgId: 1f23f6a703ef9bc0cc895bbad34adff79860353702b70941c320d0cee24bcbb9
name: python-brom-drake
arch: src
version: 0.2.9
epoch: 0
release: 1
summary: A set of convenient logging and testing tools for the Drake robotics toolbox.
url: https://github.com/kwesiRutledge/brom_drake-py
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brom-drake-0.2.9-1.src.rpm
checksum_type: sha256
description:
  [![codecov](https://codecov.io/gh/kwesiRutledge/brom_drake-py/graph/badge.svg?token=0TI5PV2HUD)](https://codecov.io/gh/kwesiRutledge/brom_drake-py)


  Brom is a helper library for the [Drake](https://drake.mit.edu/) robotics simulation and verification library.
  Its goal is to simplify common debugging and testing activities in Drake (for example, logging the outputs
  of systems in your block diagrams).

  Some of Brom's features:

  Feature                    |  Code | Results
  :-------------------------:|:-------------------------:|:-------------------------:
  The Diagram Watcher (the `DiagramWatcher` will log + plot all output ports of your `Diagram` automatically) |`add_watcher_and_build()`| ![Creation of Brom Directory](./promo/BromWatcher0.gif)
  The Drake-ify feature (converts your URDF file into a form that Drake can consume) | `drakeify_my_urdf()` | ![Drakeify Example](./promo/BromDrakeifyURDF0.gif)
  Scenes (partially complete robot scenarios to test your algorithms) | (See [Examples Directory](https://github.com/kwesiRutledge/brom_drake-py/tree/main/examples/scenes) or [the Wiki](https://github.com/kwesiRutledge/brom_drake-py/wiki/Scenes)) | ![Kinematic Motion Planning Example](./promo/scenes/motion_planning/kinematic/Chem-Lab-Demo.gif)

  (More coming soon...)



  `brom_drake` is available on PyPI and installable with pip:

  ```shell
  pip install brom-drake
  ```



  You can also install the package during local development by cloning
  the repository and running the following commands from inside it:

  ```bash
  pip install -r requirements.txt
  pip install -e .
  ```



  Here are a few of the features available in `brom_drake` and how they work.



  It is recommended that you use the convenience function `add_watcher_and_build` to add a `DiagramWatcher` to your diagram.

  ```python

  from pydrake.all import (
      DiagramBuilder, Simulator,
  )


  from brom_drake.all import add_watcher_and_build


  builder = DiagramBuilder()




  watcher, diagram, diagram_context = add_watcher_and_build(builder)


  simulator = Simulator(diagram, diagram_context)
  simulator.set_target_realtime_rate(1.0)
  simulator.set_publish_every_time_step(False)


  simulator.Initialize()
  simulator.AdvanceTo(15.0)

  ```


  What will happen whenever you use this function is that:
  - The `DiagramWatcher` will be created.
    - It will search through all systems that the `DiagramBuilder` has added.
    - For each system, the watcher will add a `VectorLogger` to each output port that is a `kVectorValued` port.
    - The `DiagramWatcher` will connect all loggers to all targeted ports (in the above case, we will target all available output ports).
  - After the simulation is run and the script completes, the watcher will save all data traces for each port in `.png` files. These plots will be in a new `.brom` directory.



  If you only want to watch a specific system, then you can do so by passing in information to the "targets" argument:
  ```python
  watcher, _, _ = add_watcher_and_build(
    builder,
    targets=[
      ("system_name", "port_name"),
      "system_name2",
    ],
  )
  ```
  The above code tells the watcher to watch the port named `port_name` on the system named `system_name`.
  (If you don't know your system's name in Drake, then you can usually find it by using the `get_name()` method.)



  Feel free to cite this project if it helped with your work!

  ```
  @misc{drake,
    author = "Kwesi Rutledge and the Wrench Robotics Team",
    title = "Brom: A Helper Library for the Drake Toolbox",
    year = 2024,
  }
  ```





  [Brom the storyteller](https://inheritance.fandom.com/wiki/Brom) is a character from the
  [Inheritance](https://en.wikipedia.org/wiki/Eragon) series by Christopher Paolini.
  He is a wise mentor that helps Eragon (the protagonist) master dragons. ;)








  Some other work in the open-source drake community:
  - [kinova_drake](https://github.com/vincekurtz/kinova_drake) - A Drake-based library that builds a
    simple version of the manipulation station for the Kinova Gen3 robot arm.
    Also works with the hardware.
  - [airo-drake](https://github.com/airo-ugent/airo-drake) - A python package meant to simplify
    working with Drake and the `airo-mono` repository from the AI and Robotics Lab at Ghent University.



  - [ ] Figure out how to tell if two systems are connected in Drake.
  - [ ] Add support for abstract output ports?
  - [ ] Add more readme explanations of what is going on under the hood.
  - [ ] Add Documentation
  - [ ] Create a method that makes each material in a URDF file have unique names if they have specific values
  - [ ] Add methods for saving the state names on state plots from diagram watcher
  - [X] Add methods for over or under-approximating complex mehes with cylinders or circles or other shapes.
  - [ ] Allow for the user to give "Drake-unfriendly" URDFs to `ShowMeThisModel` scene


pkgId: e29e623f09eee0d983100a4e2e00ab53cc8818d89c4e8d89b479ed7928075c34
name: python-brominecore
arch: src
version: 1.0
epoch: 0
release: 1
summary: Misskey websocketAPI wrapper.
url: https://pypi.org/project/brominecore/
rpm_license: MIT License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brominecore-1.0-1.src.rpm
checksum_type: sha256
description:
  [ぶろみね](https://github.com/35enidoi/bromine35bot)くんのコア部分の実装、そしてmisskeyのwebsocketAPI単体の実装です。

  ローカルのノートを講読したり、通知を取得したり。リバーシも頑張れば実装できます。

  何か問題が発生したり追加してほしい機能があったらissueに書いてください
  頑張って実装したり解決します

  簡単なタイムライン閲覧クライアントです。
  トークン無しでタイムラインをリアルタイムで閲覧できます。
  ```py
  import asyncio
  from brcore import Bromine, enum


  INSTANCE = "misskey.io"
  TL = enum.MisskeyChannelNames.LOCAL_TIMELINE


  def note_printer(note: dict) -> None:
      """ノートの情報を受け取って表示する関数"""
      NOBASIBOU_LENGTH = 20
      user = note["user"]
      username = user["name"] if user["name"] is not None else user["username"]
      print("-"*NOBASIBOU_LENGTH)
      if note.get("renoteId") and note["text"] is None:
          
          print(f"{username}がリノート")
          note_printer(note["renote"])
          
          
          print("-"*NOBASIBOU_LENGTH)
          return
      else:
          
          print(f"{username}がノート ノートid: {note['id']}")
      if note.get("reply"):
          
          print("リプライ:")
          note_printer(note["reply"])
      if note.get("text"):
          print("テキスト:")
          print(note["text"])
      if note.get("renoteId"):
          
          print("引用:")
          note_printer(note["renote"])
      if len(note["files"]) != 0:
          
          print(f"ファイル数: {len(note['files'])}")
      
      print(f"リプライ数: {note['repliesCount']}, リノート数: {note['renoteCount']}, リアクション数: {note['reactionCount']}")
      reactions = []
      for reactionid, val in note["reactions"].items():
          if reactionid[-3:] == "@.:":
              
              
              reactionid = reactionid[:-3] + ":"
          reactions.append(f"({reactionid}, {val})")
      if len(reactions) != 0:
          print("リアクション達: ", ", ".join(reactions))
      print("-"*NOBASIBOU_LENGTH)


  async def note_async(note: dict) -> None:
      """上のprinterの引数を調整するやつ

      asyncにするのはws_connectでは非同期関数が求められるので(見た目非同期っていう体にしているだけ)"""
      note_printer(note["body"])
      print()  # 空白をノート後に入れておく


  async def main() -> None:
      brm = Bromine(instance=INSTANCE)
      brm.ws_connect(TL, note_async)
      print("start...")
      await brm.main()


  if __name__ == "__main__":
      try:
          asyncio.run(main())
      except KeyboardInterrupt:
          print("fin")

  ```


pkgId: c886da098d0232500ca516c99dc5f2e393def0975786cee555ba7151df15a2e7
name: python-bronotes
arch: src
version: 2.4.1
epoch: 0
release: 1
summary: A commandline note organization tool.
url: https://github.com/jwizzle/bronotes
rpm_license: MIT License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-bronotes-2.4.1-1.src.rpm
checksum_type: sha256
description:
  Basically a wrapper to access notes in a directory on your system anywhere from the commandline. And keep it in sync with git.

  Functionality so far:
    * Create a note directory on your system on first start
    * Add new notes
    * Remove notes
    * Move notes and directories around
    * Edit notes with your $EDITOR
    * List notes dir in a tree
    * Generate autocompletions for zsh
    * Execute arbitrary commands in the notes directory
    * The show and edit actions search for matching notes if no valid path is given



  ```bash
  $ pip install bronotes
  ```

  On first command a folder to be used is asked.



  For now there's no built-in completions.
  ZSH completions can be generated so you can place them where needed:
  ```bash
  $ bnote completions | tee ~/.oh-my-zsh/completions/_BRONOTES
  ```



  By default this wraps any shell command you feed it and executes it in your notes directory. When using any of the defined actions (see bnote -h) it will do that instead.
  The default can be changed, and the regular shell alternatives for actions like 'rm' can be used by just using the 'exec' action manually.

  ```bash
  $ bnote -h # For actions overview, actions have their own sub help-pages.
  ```

  ```bash
  $ bnote list
  .notes/
  |-- baewfweiogn
  |-- testblaat.md
  |-- blarpblarp.md
  ```

  ```bash
  $ bnote madness # madness is a great way to browse your markdown files in a local server
         start  the madness
           env  production
        listen  0.0.0.0:3000
  ```

  * Subcommands have their own help pages.
  * When using the edit or show subcommand, it falls back on the -s option if the path to your note is not valid.
  * If the first argument given is not recognized by bronotes, a default action will be taken and the first argument will be fed to that action instead. This is configurable with the 'set' action and defaults to 'exec'



  You can use the sync command to keep a repo in sync with git. Using basic pull/push on master.
  If you want to have more control simply don't use this.
  If the repo isn't a git repo yet you will be asked to initialize an empty one and set up remotes.
  When quit halfway through this process it's probably better to either start over or just fix it manually.

  Autosyncing is possible, but will do so after every edit or add action. So figure out if you want that yourself.


pkgId: 538c80124c1a862a36d89557d0aad37c28ea8eadc7ecc8ee0ed6f9be793a68e0
name: python-broqer
arch: src
version: 3.0.3
epoch: 0
release: 1
url: https://github.com/semiversus/python-broqer
rpm_license: MIT license
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-broqer-3.0.3-1.src.rpm
checksum_type: sha256
summary:
  Carefully crafted library to operate with continuous streams of data in a reactive style with publish/subscribe and broker functionality.


pkgId: 9ae91af8421c9fd6805780d32e736ed2e463f5893cb9cec84013a915019a1ae6
name: python-brother
arch: src
version: 4.3.1
epoch: 0
release: 1
summary: Python wrapper for getting data from Brother laser and inkjet printers via SNMP.
url: https://github.com/bieniu/brother
rpm_license: Apache-2.0 License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brother-4.3.1-1.src.rpm
checksum_type: sha256
description:
  [![GitHub Release][releases-shield]][releases]
  [![PyPI][pypi-releases-shield]][pypi-releases]
  [![PyPI - Downloads][pypi-downloads]][pypi-statistics]
  [![Buy me a coffee][buy-me-a-coffee-shield]][buy-me-a-coffee]
  [![PayPal_Me][paypal-me-shield]][paypal-me]



  Python wrapper for getting data from Brother laser and inkjet printers via snmp



  ```py
  import asyncio
  import logging
  from sys import argv

  import pysnmp.hlapi.asyncio as hlapi

  from brother import Brother, SnmpError, UnsupportedModelError


  HOST = "brother"
  logging.basicConfig(level=logging.DEBUG)


  async def main():
      host = argv[1] if len(argv) > 1 else HOST
      printer_type = argv[2] if len(argv) > 2 else "laser"
      
      

      external_snmp = False
      if len(argv) > 3 and argv[3] == "use_external_snmp":
          external_snmp = True

      if external_snmp:
          print("Using external SNMP engine")
          snmp_engine = hlapi.SnmpEngine()
      else:
          snmp_engine = None
      try:
          brother = await Brother.create(
              host, printer_type=printer_type, snmp_engine=snmp_engine
          )
          data = await brother.async_update()
      except (ConnectionError, SnmpError, UnsupportedModelError) as error:
          print(f"{error}")
          return

      brother.shutdown()

      print(f"Model: {brother.model}")
      print(f"Firmware: {brother.firmware}")
      if data:
          print(f"Status: {data.status}")
          print(f"Serial no: {data.serial}")
          print(f"Sensors data: {data}")


  loop = asyncio.new_event_loop()
  loop.run_until_complete(main())
  loop.close()
  ```

  [releases]: https://github.com/bieniu/brother/releases
  [releases-shield]: https://img.shields.io/github/release/bieniu/brother.svg?style=popout
  [pypi-releases]: https://pypi.org/project/brother/
  [pypi-statistics]: https://pepy.tech/project/brother
  [pypi-releases-shield]: https://img.shields.io/pypi/v/brother
  [pypi-downloads]: https://pepy.tech/badge/brother/month
  [buy-me-a-coffee-shield]: https://img.shields.io/static/v1.svg?label=%20&message=Buy%20me%20a%20coffee&color=6f4e37&logo=buy%20me%20a%20coffee&logoColor=white
  [buy-me-a-coffee]: https://www.buymeacoffee.com/QnLdxeaqO
  [paypal-me-shield]: https://img.shields.io/static/v1.svg?label=%20&message=PayPal.Me&logo=paypal
  [paypal-me]: https://www.paypal.me/bieniu79


pkgId: 58d6d89efece6e629e8b96196312e5fe9a860e71c49ec76568a60d49f1c7144e
name: python-brother-label
arch: src
version: 2.0a8
epoch: 0
release: 1
summary: Brother label printer interface for QL and PT series printers.
url: https://pypi.org/project/brother-label/
rpm_license: GPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brother-label-2.0a8-1.src.rpm
checksum_type: sha256
description:
  Brother label printer interface for QL and PT series printers.

  **API is currently being re-worked and should not be considered stable.**

  Fork of https://github.com/pklaus/brother_ql and https://github.com/matmair/brother_ql-inventree with many
  improvements and features planned, including:

  - Better support for device-specific label specifications (e.g. QL vs PT)
  - Support for new devices (PT-E550W)
  - Removed redudant legacy/compatibility code
  - ...



  | Device           | Status       |
  | ---------------- | ------------ |
  | QL-500           | Supported    |
  | QL-550           | Supported    |
  | QL-560           | Supported    |
  | QL-570           | Supported    |
  | QL-580N          | Supported    |
  | QL-600           | Supported    |
  | QL-650TD         | Supported    |
  | QL-700           | Supported    |
  | QL-710W          | Supported    |
  | QL-720NW         | Supported    |
  | QL-800           | Supported    |
  | QL-810W          | Supported    |
  | QL-820NWB        | Supported    |
  | QL-1050          | Supported    |
  | QL-1060N         | Supported    |
  | QL-1100          | Supported    |
  | QL-1100NWB       | Supported    |
  | QL-1115NWB       | Supported    |
  | PT-P750W         | Supported    |
  | PT-P900W         | Supported    |
  | PT-P950NW        | Supported    |
  | PT-E550W         | ✔️ Verified |

   - **Supported:** Device is supported, but no verification has been received.
   - **Verified:** Device is supported, and verified by a user.





  | Type             | QL     | QL-10  | QL-11  | PT    | PT-E  |
  | ---------------- | ------ | ------ | ------ | ----- | ------ |
  | 6                | ❌    | ❌    | ❌    | ❌    | ✔️    |
  | 9                | ❌    | ❌    | ❌    | ❌    | ✔️    |
  | 12               | ✔️    | ✔️    | ✔️    | ✔️    | ✔️    |
  | 18               | ✔️    | ✔️    | ✔️    | ✔️    | ✔️    |
  | 24               | ❌    | ❌    | ❌    | ✔️    | ✔️    |
  | 29               | ✔️    | ✔️    | ✔️    | ❌    | ❌    |
  | 36               | ❌    | ❌    | ❌    | ✔️    | ✔️    |
  | 38               | ✔️    | ✔️    | ✔️    | ❌    | ❌    |
  | 50               | ✔️    | ✔️    | ✔️    | ❌    | ❌    |
  | 54               | ✔️    | ✔️    | ✔️    | ❌    | ❌    |
  | 62               | ✔️    | ✔️    | ✔️    | ❌    | ❌    |
  | 62red            | ✔️    | ✔️    | ✔️    | ❌    | ❌    |
  | 102              | ❌    | ✔️    | ❌    | ❌    | ❌    |
  | 103              | ❌    | ❌    | ✔️    | ❌    | ❌    |
  | 104              | ❌    | ✔️    | ❌    | ❌    | ❌    |



  | Type             | QL     | QL-10  | QL-11 |
  | ---------------- | ------ | ------ | ----- |
  | 17x54            | ✔️    | ✔️    | ✔️    |
  | 17x87            | ✔️    | ✔️    | ✔️    |
  | 23x23            | ✔️    | ✔️    | ✔️    |
  | 29x42            | ✔️    | ✔️    | ✔️    |
  | 29x90            | ✔️    | ✔️    | ✔️    |
  | 39x90            | ✔️    | ✔️    | ✔️    |
  | 39x48            | ✔️    | ✔️    | ✔️    |
  | 52x29            | ✔️    | ✔️    | ✔️    |
  | 54x29            | ✔️    | ✔️    | ✔️    |
  | 60x86            | ✔️    | ✔️    | ✔️    |
  | 62x29            | ✔️    | ✔️    | ✔️    |
  | 62x100           | ✔️    | ✔️    | ✔️    |
  | 102x51           | ❌    | ✔️    | ❌    |
  | 102x152          | ❌    | ✔️    | ❌    |
  | 103x164          | ❌    | ❌    | ✔️    |



  | Type             | QL     | QL-10  | QL-11  |
  | ---------------- | ------ | ------ | ------ |
  | d12              | ✔️    | ✔️    | ✔️    |
  | d24              | ✔️    | ✔️    | ✔️    |
  | d58              | ✔️    | ✔️    | ✔️    |



  | Backend       | Type | Linux | Mac OS | Windows |
  | ------------- | ---- | ----- | ------ | ------- |
  | network       | TCP  | ✔️   | ✔️     | ✔️     |
  | linux\_kernel | USB  | ✔️   | ❌     | ❌     |
  | py_usb        | USB  | ✔️   | ✔️     | ✔️     |


pkgId: 95a8e1ca37d2a2f9906b33c353defaa9aaa572f211bb568bcbdd905db3e2883a
name: python-brother-ql
arch: src
version: 0.9.4
epoch: 0
release: 1
summary: Python package to talk to Brother QL label printers
url: https://github.com/pklaus/brother_ql
rpm_license: GPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brother-ql-0.9.4-1.src.rpm
checksum_type: sha256
description:
  A Python package to control Brother QL label printers. It implements the
  raster language of those printers and allows you to send instruction
  files to your printer. In more details, the following is possible with
  this package:
  -  Create raster language files for the Brother label printers. They can
     be created from image files or programmatically in your own Python
     script.
  -  Print raster instruction files with your Brother label printer via
     different backends:
     -  pyusb (works cross-platform)
     -  network (works cross-platform for WiFi/Ethernet-enabled printers)
     -  linux_kernel (works on Linux only; uses the /dev/usb/lp0 device
        handles)
  The following printers are claimed to be supported (✓ means verified by
  the author or by contributors):
  -  QL-500 (✓), QL-550 (✓), QL-560 (✓), QL-570 (✓), QL-580N, QL-650TD,
     QL-700 (✓), QL-710W (✓), QL-720NW (✓), QL-800 (✓), QL-810W (✓),
     QL-820NWB (✓), QL-1050 (✓), and QL-1060N (✓).
  The new QL-800 series can print labels with two colors (black and red)
  on DK-22251 labels.
  Note: If your printer has an ‘Editor Lite’ mode, you need to disable it
  if you want to print via USB. Make sure that the corresponding LED is
  not lit by holding the button down until it turns off.
  If you’re interested in printing labels using a web interface, check out
  `brother_ql_web <https://github.com/pklaus/brother_ql_web>`__, which
  builds upon this package.


pkgId: 76203f5be1d723ed04cc2b4885acacd5fdf8306222acce221bc288a11ebb96cf
name: python-brother-ql-inventree
arch: src
version: 1.3
epoch: 0
release: 1
summary: Python package to talk to Brother QL label printers
url: https://github.com/matmair/brother_ql-inventree
rpm_license: GPL
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brother-ql-inventree-1.3-1.src.rpm
checksum_type: sha256
description:
  network (1) | TCP | ✔ | ✔ | ✔
  linux\_kernel | USB | ✔ (2) | ✘ | ✘
  pyusb (3) | USB | ✔ (3.1) | ✔ (3.2) | ✔ (3.3)
  Warning: when using one of the USB backends make sure the Editor Lite feature is turned off (if your model supports it), otherwise the USB Printer interface won't be detected.

  v 1.3:
  - Added detection of more media and commands to list and configure settings https://github.com/matmair/brother_ql-inventree/pull/57
  - Added new cli command for getting the status of printers https://github.com/matmair/brother_ql-inventree/pull/53
  v1.2:
  - Remove support for Python 2 https://github.com/matmair/brother_ql-inventree/pull/43 / https://github.com/matmair/brother_ql-inventree/pull/45
  - Added support for PT-E550W https://github.com/matmair/brother_ql-inventree/pull/44
  - Added label support for 12+17 https://github.com/matmair/brother_ql-inventree/pull/42
  v1.1:
  - Support for Pillow 10.x https://github.com/matmair/brother_ql-inventree/pull/37
  v1.0:
  - Renamed the package to `brother_ql-inventree` and added a release action https://github.com/matmair/brother_ql-inventree/pull/16
  - Added printer support for QL-600 https://github.com/matmair/brother_ql-inventree/pull/17 , PT-P950NW https://github.com/matmair/brother_ql-inventree/pull/6 , QL-1100, L-1100NWB, QL-1115NWB https://github.com/matmair/brother_ql-inventree/pull/18
  - Added label support for DK-1234 https://github.com/matmair/brother_ql-inventree/pull/22 , 54x29  https://github.com/matmair/brother_ql-inventree/pull/19 , DK22246 https://github.com/matmair/brother_ql-inventree/pull/20, ...
  Read the full old Readme [here](https://github.com/matmair/brother_ql-inventree/blob/cleanup/OLD_README.md).


pkgId: da736bfe1813993cc7f518dfd168c5df0ac96dd08b808d6e4e24bba3a4336bd5
name: python-brotli-asgi
arch: src
version: 1.4.0
epoch: 0
release: 1
summary: A compression AGSI middleware using brotli
url: https://github.com/fullonic/brotli-asgi
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brotli-asgi-1.4.0-1.src.rpm
checksum_type: sha256
description:
  A compression AGSI middleware using brotli.

  Built using starlette under the hood, it can be used as a drop-in replacement to
  GZipMiddleware for Starlette or FastAPI.


pkgId: 4826f54c551bb3166b77a1cf747127b0f3271a617d2a36739786159aad93dcb9
name: python-brotlipy
arch: src
version: 0.7.0
epoch: 0
release: 1
summary: Python binding to the Brotli library
url: https://github.com/python-hyper/brotlipy/
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brotlipy-0.7.0-1.src.rpm
checksum_type: sha256
description:
  This library contains Python bindings for the reference Brotli encoder/decoder,
  `available here`_. This allows Python software to use the Brotli compression
  algorithm directly from Python code.
  To use it simply, try this:
      import brotli
      data = brotli.decompress(compressed_data)
  More information can be found `in the documentation`_.


pkgId: 1dbe61595579520b70a25327d21ef85988e19847f390d990d7fb1197eb89e885
name: python-brown-logger
arch: src
version: 0.1.0
epoch: 0
release: 1
summary: A Singleton Logger implementation with console and file logging support
url: https://github.com/iamlamm/brown-logger
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brown-logger-0.1.0-1.src.rpm
checksum_type: sha256
description:
  A Singleton Logger implementation that supports both console and file logging.



  - Singleton pattern ensures only one logger instance exists
  - Supports both console and file logging
  - Rotating file handler to manage log file sizes
  - Message caching for debug and info levels
  - Dynamic log level adjustment
  - Context manager support



  pip install brown-logger

rpm_license:
  MIT License  Copyright (c) 2024 Lâm  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: 33ea348474d00386df8b40ee4da51392d9495349a2d9c36c845233c9b1726aca
name: python-brownian-stock
arch: src
version: 0.0.51
epoch: 0
release: 1
summary: Add your description here
url: https://pypi.org/project/brownian-stock/
rpm_license: UNKNOWN
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brownian-stock-0.0.51-1.src.rpm
checksum_type: sha256
description:
  [![Python application](https://github.com/toritoritori29/brownian/actions/workflows/python-app.yml/badge.svg?branch=main)](https://github.com/toritoritori29/brownian/actions/workflows/python-app.yml)

  Brownianは日本株取引に対応した株取引フレームワークです。JQuantsからのデータダウンロード, 取引モデルの作成, バックテスト, 実取引まで網羅的にサポートします.





  以下のサブコマンドを実行すると指定したディレクトリ以下にJQuantesから取得した情報をCSVで保存します.
  ```
  brownian download <保存先のディレクトリ名>
  ```


  またdownloadオプションには`--username`および`--password`オプションが用意されていて、実行時にこれらの引数を指定して実行することもできます。
  これらの引数は.brownianrcの内容より優先して利用されます。


  以下のコマンドを実行すると, ダウンロードしたデータを集計してSQLiteデータベース上に格納します.
  またデータベースから銘柄毎の株価情報・決算情報を集計しCSVを生成します.

  ```
  $ brownian download <保存先フォルダ名>
  $ brownian generate <保存先フォルダ名>
  ```




  JQuantsから取得した日毎の株価情報


  JQuantsから取得した日毎の決算情報


  `genereate`コマンドで生成した銘柄毎の株価情報.　株価は調整済みの数字.



  各種コマンドのインストール前にvenvをactivateしてください.

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




  * rye
  * gh


  Run following commands.
  ```
  rye sync
  ```



  * To test.
  ```bash
  rye run pytest
  ```

  * Lint and format
  ```bash
  rye run invoke lint
  rye run invoke format
  ```


  Run the following command.
  This command increment the version number and make a release PR.
  ```bash
  .bump_version.sh
  ```



  ```bash
  rye run brownian ...
  ```


pkgId: 2fbbef4ba5adeb35165092c7c2a2ba936e040f2cc42f54dcb05c481941f0922a
name: python-brownie-token-tester
arch: src
version: 0.3.2
epoch: 0
release: 1
summary: Helper objects for generating ERC20s while testing a Brownie project.
url: https://github.com/iamdefinitelyahuman/brownie-token-tester
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brownie-token-tester-0.3.2-1.src.rpm
checksum_type: sha256
description:
  Helper objects for generating ERC20s while testing a Brownie project.



  - [python3](https://www.python.org/downloads/release/python-368/) version 3.6 or greater, python3-dev
  - [brownie](https://github.com/eth-brownie/brownie) version [1.11.6](https://github.com/eth-brownie/brownie/releases/tag/v1.11.6) or greater
  - [ganache-cli](https://github.com/trufflesuite/ganache-cli) version [6.11.0](https://github.com/trufflesuite/ganache-cli/releases/tag/v6.11.0) or greater





  If you have installed Brownie using [`pipx`](https://github.com/pipxproject/pipx), you need to add `brownie-token-tester` into the same virtual environment:

  ```bash
  pipx inject eth-brownie brownie-token-tester
  ```



  You can install the latest release via [`pip`](https://pypi.org/project/pip/):

  ```bash
  pip install brownie-token-tester
  ```



  You can clone the repository and use [`setuptools`](https://github.com/pypa/setuptools) for the most up-to-date version:

  ```bash
  git clone https://github.com/iamdefinitelyahuman/brownie-token-tester.git
  cd brownie-token-tester
  python3 setup.py install
  ```



  Import the library from within a Brownie test, script or console:

  ```python
  from brownie_tokens import ERC20, MintableForkToken
  ```

  You can then make use of the following functionality:



  Deploys a generic ERC20 contract for testing purposes.

  ```python
  def ERC20(
      name: str = "Test Token",
      symbol: str = "TST",
      decimals: int = 18,
      success: Union[bool, None] = True,
      fail: Union[bool, str, None] = "revert",
  ) -> Contract:
  ```

  - The `success` kwarg is used to set the token's return value upon a successful call to `approve`, `transfer` or `transferFrom`. Valid values are `True`, `False`, and `None`.
  - The `fail` kwarg sets the token's behaviour upon failed calls to the above methods. Use `"revert"` if the transaction should revert, or `True`, `False`, and `None` to return a value without reverting.

  The resulting deployment adheres to the [ERC20 Token Standard](https://eips.ethereum.org/EIPS/eip-20) and additionally implements one non-standard method:

  ```python
  def _mint_for_testing(target: address, amount: uint256): nonpayable
  ```

  This method increases the balance of `target` by `amount`. It may be called by any account.



  `MintableForkToken` is used to standardize the process of minting tokens when working in a [forked mainnet](https://eth-brownie.readthedocs.io/en/stable/network-management.html#using-a-forked-development-network) environment. The `MintableForkToken` class inherits from and may be used interchangeably with the [`Contract`](https://eth-brownie.readthedocs.io/en/stable/api-network.html#contract-and-projectcontract) class. It exposes one additional method, `_mint_for_testing`, with the same API as given above.

  For tokens where [custom logic is implemented](https://github.com/iamdefinitelyahuman/brownie-token-tester/blob/master/brownie_tokens/forked.py#L52), this is an actual minting event. For most tokens, the "minting" process involves a query to the [Ethplorer API](https://github.com/EverexIO/Ethplorer/wiki/Ethplorer-API#get-top-token-holders) to get a list of top token holders, and then transferring their balances to `target`. If you want to exclude some holders from this process use `skip_holders(*addresses)`. If you have too many requests at a time set `$ETHPLORER_API_KEY`(see [ethplorer.io](https://ethplorer.io)) as environment variable.

  Tokens for which custom logic is currently implemented:

  - [x] Aave tokens
  - [x] DAI
  - [x] EURS
  - [x] LinkUSD
  - [x] pBTC
  - [x] Synthetix synths
  - [x] renBTC
  - [x] renZEC
  - [x] rETH
  - [x] RSV
  - [x] USDC
  - [x] USDN
  - [x] USDT
  - [x] tBTC
  - [x] wBTC
  - [x] wZEC



  This project is still in early development and should be considered an alpha. Comments, questions, criticisms and pull requests are welcomed.



  This project is licensed under the [MIT license](LICENSE).


pkgId: b7a0448111612d0fa91fc29b2feda1f16e0420fe9a7395638859a0a2461eac81
name: python-browse-ocrd
arch: src
version: 0.5.5
epoch: 0
release: 1
summary: An extensible viewer for OCR-D workspaces
url: https://github.com/hnesk/browse-ocrd
rpm_license: MIT License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browse-ocrd-0.5.5-1.src.rpm
checksum_type: sha256
description:
  [![Unit tests](https://github.com/hnesk/browse-ocrd/workflows/Unit%20tests/badge.svg?branch=master)](https://github.com/hnesk/browse-ocrd/actions/workflows/unittest.yml)
  [![Docker build](https://github.com/hnesk/browse-ocrd/actions/workflows/dockerhub.yml/badge.svg)](https://github.com/hnesk/browse-ocrd/actions/workflows/dockerhub.yml)
  [![PyPI version](https://badge.fury.io/py/browse-ocrd.svg)](https://badge.fury.io/py/browse-ocrd)


  An extensible viewer for [OCR-D](https://ocr-d.de/) [mets.xml](https://ocr-d.de/en/spec/mets) files

   * [Screenshot](#screenshot)
   * [Features](#features)
   * [Installation](#installation)
      * [Native](#native-tested-on-ubuntu-18042004)
         * [From source](#from-source)
         * [Via pip](#via-pip)
      * [Docker](#docker)
   * [Usage](#usage)
      * [Native GUI](#native-gui)
      * [Docker service](#docker-service)
   * [Configuration](#configuration)
      * [Configuration file locations](#configuration-file-locations)
      * [Configuration file syntax](#configuration-file-syntax)



  ![OCRD Browser with Page and Xml view](docs/screenshot.png)




  - Browse fileGrps and pages, arranging views next to each other for comparison
  - PageView: Show original or derived page images with [PAGE-XML](https://ocr-d.de/en/spec/page) annotations overlay, similar to [PageViewer](https://github.com/PRImA-Research-Lab/prima-page-viewer)
  - ImageView: Show original or derived images (`AlternativeImage` on any level of the structural hierarchy)
  - ImageView: Show multiple images at once for different pages (horizontally) or different segments (vertically), zooming freely
  - XmlView: Show raw [PAGE-XML](https://ocr-d.de/en/spec/page) with syntax highlighting, open with [PageViewer](https://github.com/PRImA-Research-Lab/prima-page-viewer)
  - TextView: Show concatenated [PAGE-XML](https://ocr-d.de/en/spec/page) text annotation
  - DiffView: Show a simple diff comparison between text annotations from different fileGrps
  - HtmlView: Show rendered HTML comparison from [dinglehopper](https://github.com/qurator-spk/dinglehopper) evaluations



  OCR-D Browser requires Python 3.7 or higher.



  The native installation requires [GTK 3](https://www.gtk.org/).

  In any case you need a [virtual environment](https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments) with a current `pip` version (>=20), preferably your existing OCR-D venv:

  <details>
    <summary>Create a current pip venv:</summary>

  ```bash
  sudo apt install python3-pip python3-venv
  python3 -m venv venv
  source venv/bin/activate
  pip install --upgrade pip setuptools wheel
  ```
  </details>



  ```bash
  git clone https://github.com/hnesk/browse-ocrd.git
  cd browse-ocrd
  sudo make deps-ubuntu
  make install
  ```



  ```bash
  sudo apt install libcairo2-dev libgirepository1.0-dev
  pip install browse-ocrd
  ```



  If you have installed [Docker](https://docs.docker.com/get-docker/), you can build OCR-D Browser as a **web service**:

      docker build -t ocrd_browser .

  Or use a prebuilt image from Dockerhub:

      docker pull hnesk/ocrd_browser





  Start the app with the filesystem path to the METS file of your [OCR-D workspace](https://ocr-d.de/en/spec/glossary#workspace):
  ```
  browse-ocrd ./path/to/mets.xml
  ```

  You can still open another METS file from the UI though.



  When running the webservice, you need to pass a directory `DATADIR` which (recursively) contains all the workspaces you want to serve.
  The top entrypoint `http://localhost/` will show an index page with a link `http://localhost/browse/...` for each workspace path.
  Each link will run `browse-ocrd` at that workspace in the background, and then redirect your browser to the internal [Broadway server](https://docs.gtk.org/gtk3/broadway.html), which renders the app in the web browser.

  To start up, just do:

      docker run -it --rm -v DATADIR:/data -p 8085:8085 -p 8080:8080 ocrd_browser






  At startup the following directories a searched for a config file named `ocrd-browser.conf`

  ```python

  GLib.get_system_config_dirs()  # '/etc/xdg/xdg-ubuntu/ocrd-browser.conf', '/etc/xdg/ocrd-browser.conf'
  GLib.get_user_config_dir()     # '/home/jk/.config/ocrd-browser.conf'
  os.getcwd()                    # './ocrd-browser.conf'
  ```



  The `ocrd-browser.conf` file is an ini-file with the following sections and keys:
  ```ini
  [FileGroups]


  preferredImages = OCR-D-IMG, OCR-D-IMG.*, ORIGINAL



  [Tool PageViewer]

  commandline = /usr/bin/java -jar /home/jk/bin/JPageViewer/JPageViewer.jar --resolve-dir {workspace.directory} {file.path.absolute}
  ```

  > Note: You can get PRImA's PageViewer at [Github](https://github.com/PRImA-Research-Lab/prima-page-viewer/releases).


  The `commandline` string will be used as a python format string with the keyword arguments:

  * `workspace` : The current `ocrd.Workspace`, all properties get shell escaped (by `shlex.quote`) automatically.
  * `file` : The current `ocrd_models.OcrdFile`, all properties get shell escaped (by `shlex.quote`) automatically, also there is an additional property `path` with the properties `absolute` and `relative`, so `{file.path.absolute}` will be replaced by the shell quoted absolute path of the file.



  It is possible to set or override values of the configuration through environment variables. The environment variables follow this structure :  `BROCRD__{SECTION}__{KEY}`, where `SECTION` and `KEY` are in upper snake case and divided by a double underscore (`__`). If the section title contains spaces, the single words are also divided by `__`.

  Some examples:
  ```shell
  BROCRD__FILE_GROUPS__PREFERRED_IMAGES='THUMB'
  BROCRD__TOOL__PAGEVIEWER__COMMANDLINE='ls {file.path.absolute}'

  ```


pkgId: 8bb8c91aee77c0697ace2343569312455feac086e2493ab9d550f419fa9e4b41
name: python-browser-cookie3
arch: src
version: 0.19.1
epoch: 0
release: 1
url: https://github.com/borisbabic/browser_cookie3
rpm_license: lgpl
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browser-cookie3-0.19.1-1.src.rpm
checksum_type: sha256
summary:
  Loads cookies from your browser into a cookiejar object so can download with urllib and other libraries the same content you see in the web browser.


pkgId: 7f2febe85efb28790da4714909eb71af84fa4ee6e0968b105ea1bd2b4f9be3ca
name: python-browser-history
arch: src
version: 0.4.1
epoch: 0
release: 1
summary: A python module to extract browser history
url: https://github.com/browser-history/browser-history
rpm_license: Apache License 2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browser-history-0.4.1-1.src.rpm
checksum_type: sha256
description:
  <p align="center" width="100%">
      <img width="33%" src="https://github.com/browser-history/browser-history/blob/master/logo.png?raw=true">
  </p>

  <h1 align="center"> browser-history</h1>

  ![tests](https://github.com/browser-history/browser-history/workflows/tests/badge.svg)
  [![Documentation Status](https://readthedocs.org/projects/browser-history/badge/?version=latest)](https://browser-history.readthedocs.io/en/latest/?badge=latest)
  [![PyPI version](https://badge.fury.io/py/browser-history.svg)](https://badge.fury.io/py/browser-history)
  [![codecov](https://codecov.io/gh/browser-history/browser-history/branch/master/graph/badge.svg)](https://codecov.io/gh/browser-history/browser-history)
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
  [![Maintainability](https://api.codeclimate.com/v1/badges/64c86a28b0d7d387ce72/maintainability)](https://codeclimate.com/github/browser-history/browser-history/maintainability)

  ``browser-history`` is a simple, zero-dependencies, developer-friendly python
  package to retrieve (almost) any browser's history on (almost) any platform.




   - Supports most **popular browsers**. See [this](https://browser-history.readthedocs.io/en/latest/browsers.html) for a full list.
   - Supports all major platforms - **Windows, Mac and Linux**.
   - A **command-line tool**: simply run `browser-history --help` from your terminal.
   - **History**: browsing history with exact timestamp and URL.
   - **Bookmarks**: browser bookmarks with timestamp, URL, title and folder.
   - Lightweight: the entire package is less than 20kB in size and has no dependencies other than python 3.7+.
   - Developer friendly: you can add support for new browsers or add a new feature very easily.
   - Default browser: can automatically determine the default browser on Windows and Linux (`browser-history -b default`).
   - Fully open source: this project is developed and maintained by the [`browser-history` organization](https://github.com/browser-history) (previously maintained by [PESOS](https://github.com/pesos)) and will always be open source (with the Apache 2.0 License).





  To install the latest release:

  ```
  pip install browser-history
  ```

  To install from the master branch (warning: development version. Things could break)

  ```
  pip install git+https://github.com/browser-history/browser-history.git
  ```





  To get history from all installed browsers:
  ```python
  from browser_history import get_history

  outputs = get_history()


  his = outputs.histories
  ```

  If you want history from a specific browser:
  ```python
  from browser_history.browsers import Firefox

  f = Firefox()
  outputs = f.fetch_history()


  his = outputs.histories
  ```

   - `Firefox` in the above snippet can be replaced with any of the [supported browsers](https://browser-history.readthedocs.io/en/latest/browsers.html).



  WARNING: Experimental feature. Although this has been confirmed to work on multiple (Firefox and Chromium based) browsers
  on all platforms, it is not covered by tests and has not been used as much as the history feature.

  To get bookmarks from all installed browsers:
  ```python
  from browser_history import get_bookmarks

  outputs = get_bookmarks()


  bms = outputs.bookmarks
  ```

  To get bookmarks from a specific browser:
  ```python
  from browser_history.browsers import Firefox

  f = Firefox()
  outputs = f.fetch_bookmarks()


  bms = outputs.bookmarks
  ```

  Check out the [documentation](https://browser-history.readthedocs.io/en/latest/) for more details.



  Read the [documentation](https://browser-history.readthedocs.io/en/latest/browsers.html)



  Logo designed with :heart: by [XA](https://github.com/XAMES3).



  Licensed under the [Apache License, Version 2.0 (the "License")](LICENSE)


pkgId: 35991e7edc272c45c5237d249d84e9c75e00baf05d134579617d3abc38a59c42
name: python-browser-use
arch: src
version: 0.1.1
epoch: 0
release: 1
summary: Let LLMs interact with websites through a simple interface
url: https://pypi.org/project/browser-use/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browser-use-0.1.1-1.src.rpm
checksum_type: sha256
description:
  <div align="center">
    <b>Star ⭐ this repo if you find it useful!</b><br>
    Made with ❤️ by the Browser-Use team
  </div>


pkgId: 9bd8e2afa22b3c35eefa0f5616a8315980b97f8d688f2bcfef55670a6fb65a8d
name: python-browserbase
arch: src
version: 0.3.3
epoch: 0
release: 1
summary: Browserbase Python SDK
url: https://browserbase.com
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browserbase-0.3.3-1.src.rpm
checksum_type: sha256
description:
  <p align="center">
      <picture>
          <source media="(prefers-color-scheme: dark)" srcset="logo/dark.svg"/>
          <img alt="Browserbase logo" src="logo/light.svg" width="300" />
      </picture>
  </p>

  <p align="center">
      <a href="https://docs.browserbase.com">Documentation</a>
      <span>&nbsp;·&nbsp;</span>
      <a href="https://www.browserbase.com/playground">Playground</a>
  </p>
  <br/>



  [Browserbase](https://browserbase.com) is a serverless platform for running headless browsers, it offers advanced debugging, session recordings, stealth mode, integrated proxies and captcha solving.



  - Get an API key from [browserbase.com](https://browserbase.com) and set it in environment variables (`BROWSERBASE_API_KEY`).
  - Install the required dependencies:

  ```sh
  pip install browserbase
  ```



  ```py
  from browserbase import Browserbase


  browserbase = Browserbase(os.environ["BROWSERBASE_API_KEY"])


  result = browserbase.load("https://example.com")


  result = browserbase.load(["https://example.com"])


  result = browserbase.load("https://example.com", text_content=True)


  result = browserbase.screenshot("https://example.com", full_page=True)
  ```


pkgId: 5b2bf8d3ccd8cbeb080f36de95134b93af2a62d21397f4efcc542c9a9d255fc2
name: python-browserbase
arch: src
version: 1.0.0
epoch: 0
release: 1
summary: The official Python library for the Browserbase API
url: https://github.com/browserbase/sdk-python
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browserbase-1.0.0-1.src.rpm
checksum_type: sha256
description:
  [![PyPI version](https://img.shields.io/pypi/v/browserbase.svg)](https://pypi.org/project/browserbase/)

  The Browserbase Python library provides convenient access to the Browserbase REST API from any Python 3.7+
  application. The library includes type definitions for all request params and response fields,
  and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).

  It is generated with [Stainless](https://www.stainlessapi.com/).



  The REST API documentation can be found on [docs.browserbase.com](https://docs.browserbase.com). The full API of this library can be found in [api.md](https://github.com/browserbase/sdk-python/tree/main/api.md).



  ```sh

  pip install browserbase
  ```



  The full API of this library can be found in [api.md](https://github.com/browserbase/sdk-python/tree/main/api.md).

  ```python
  import os
  from playwright.sync_api import Playwright, sync_playwright
  from browserbase import Browserbase

  BROWSERBASE_API_KEY = os.environ.get("BROWSERBASE_API_KEY")
  BROWSERBASE_PROJECT_ID = os.environ.get("BROWSERBASE_PROJECT_ID")

  bb = Browserbase(
      
      api_key=BROWSERBASE_API_KEY,
  )

  session = client.sessions.create(
      project_id=BROWSERBASE_PROJECT_ID,
  )
  print(session.id)

  def run(playwright: Playwright) -> None:
      
      chromium = playwright.chromium
      browser = chromium.connect_over_cdp(session.connect_url)
      context = browser.contexts[0]
      page = context.pages[0]

      
      page.goto("https://news.ycombinator.com/")
      page_title = page.title()
      assert (
          page_title == "Hacker News"
      ), f"Page title is not 'Hacker News', it is '{page_title}'"
      page.screenshot(path="screenshot.png")

      page.close()
      browser.close()
      print("Done!")


  if __name__ == "__main__":
      with sync_playwright() as playwright:
          run(playwright)
  ```


  See the [examples](https://github.com/browserbase/sdk-python/tree/main/examples) directory for more usage examples.

  > [!NOTE]
  > Running the examples requires [Rye](https://rye.astral.sh/) to be installed.

  To run the examples, clone this repository and run the following commands from the project root (this directory):

  ```bash
  rye sync
  rye run example playwright_basic # replace with the example you want to run
  ```

  > [!NOTE]
  > Make sure you have a `.env` file that matches the [.env.example](https://github.com/browserbase/sdk-python/tree/main/.env.example) file in the root of this repository.



  Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Responses are [Pydantic models](https://docs.pydantic.dev) which also provide helper methods for things like:

  - Serializing back into JSON, `model.to_json()`
  - Converting to a dictionary, `model.to_dict()`

  Typed requests and responses provide autocomplete and documentation within your editor. If you would like to see type errors in VS Code to help catch bugs earlier, set `python.analysis.typeCheckingMode` to `basic`.



  When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `browserbase.APIConnectionError` is raised.

  When the API returns a non-success status code (that is, 4xx or 5xx
  response), a subclass of `browserbase.APIStatusError` is raised, containing `status_code` and `response` properties.

  All errors inherit from `browserbase.APIError`.

  ```python
  import browserbase
  from browserbase import Browserbase

  client = Browserbase()

  try:
      client.sessions.create(
          project_id="your_project_id",
      )
  except browserbase.APIConnectionError as e:
      print("The server could not be reached")
      print(e.__cause__)  # an underlying Exception, likely raised within httpx.
  except browserbase.RateLimitError as e:
      print("A 429 status code was received; we should back off a bit.")
  except browserbase.APIStatusError as e:
      print("Another non-200-range status code was received")
      print(e.status_code)
      print(e.response)
  ```

  Error codes are as followed:

  | Status Code | Error Type                 |
  | ----------- | -------------------------- |
  | 400         | `BadRequestError`          |
  | 401         | `AuthenticationError`      |
  | 403         | `PermissionDeniedError`    |
  | 404         | `NotFoundError`            |
  | 422         | `UnprocessableEntityError` |
  | 429         | `RateLimitError`           |
  | >=500       | `InternalServerError`      |
  | N/A         | `APIConnectionError`       |



  Certain errors are automatically retried 2 times by default, with a short exponential backoff.
  Connection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict,
  429 Rate Limit, and >=500 Internal errors are all retried by default.

  You can use the `max_retries` option to configure or disable retry settings:

  ```python
  from browserbase import Browserbase


  client = Browserbase(
      
      max_retries=0,
  )


  client.with_options(max_retries=5).sessions.create(
      project_id="your_project_id",
  )
  ```



  By default requests time out after 1 minute. You can configure this with a `timeout` option,
  which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/#fine-tuning-the-configuration) object:

  ```python
  from browserbase import Browserbase


  client = Browserbase(
      
      timeout=20.0,
  )


  client = Browserbase(
      timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0),
  )


  client.with_options(timeout=5.0).sessions.create(
      project_id="your_project_id",
  )
  ```

  On timeout, an `APITimeoutError` is thrown.

  Note that requests that time out are [retried twice by default](https://github.com/browserbase/sdk-python/tree/main/#retries).





  We use the standard library [`logging`](https://docs.python.org/3/library/logging.html) module.

  You can enable logging by setting the environment variable `BROWSERBASE_LOG` to `debug`.

  ```shell
  $ export BROWSERBASE_LOG=debug
  ```



  In an API response, a field may be explicitly `null`, or missing entirely; in either case, its value is `None` in this library. You can differentiate the two cases with `.model_fields_set`:

  ```py
  if response.my_field is None:
    if 'my_field' not in response.model_fields_set:
      print('Got json like {}, without a "my_field" key present at all.')
    else:
      print('Got json like {"my_field": null}.')
  ```



  The "raw" Response object can be accessed by prefixing `.with_raw_response.` to any HTTP method call, e.g.,

  ```py
  from browserbase import Browserbase

  client = Browserbase()
  response = client.sessions.with_raw_response.create(
      project_id="your_project_id",
  )
  print(response.headers.get('X-My-Header'))

  session = response.parse()  # get the object that `sessions.create()` would have returned
  print(session.id)
  ```

  These methods return an [`APIResponse`](https://github.com/browserbase/sdk-python/tree/main/src/browserbase/_response.py) object.

  The async client returns an [`AsyncAPIResponse`](https://github.com/browserbase/sdk-python/tree/main/src/browserbase/_response.py) with the same structure, the only difference being `await`able methods for reading the response content.



  The above interface eagerly reads the full response body when you make the request, which may not always be what you want.

  To stream the response body, use `.with_streaming_response` instead, which requires a context manager and only reads the response body once you call `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` or `.parse()`. In the async client, these are async methods.

  ```python
  with client.sessions.with_streaming_response.create(
      project_id="your_project_id",
  ) as response:
      print(response.headers.get("X-My-Header"))

      for line in response.iter_lines():
          print(line)
  ```

  The context manager is required so that the response will reliably be closed.



  This library is typed for convenient access to the documented API.

  If you need to access undocumented endpoints, params, or response properties, the library can still be used.



  To make requests to undocumented endpoints, you can make requests using `client.get`, `client.post`, and other
  http verbs. Options on the client will be respected (such as retries) will be respected when making this
  request.

  ```py
  import httpx

  response = client.post(
      "/foo",
      cast_to=httpx.Response,
      body={"my_param": True},
  )

  print(response.headers.get("x-foo"))
  ```



  If you want to explicitly send an extra param, you can do so with the `extra_query`, `extra_body`, and `extra_headers` request
  options.



  To access undocumented response properties, you can access the extra fields like `response.unknown_prop`. You
  can also get all the extra fields on the Pydantic model as a dict with
  [`response.model_extra`](https://docs.pydantic.dev/latest/api/base_model/#pydantic.BaseModel.model_extra).



  You can directly override the [httpx client](https://www.python-httpx.org/api/#client) to customize it for your use case, including:

  - Support for proxies
  - Custom transports
  - Additional [advanced](https://www.python-httpx.org/advanced/clients/) functionality

  ```python
  from browserbase import Browserbase, DefaultHttpxClient

  client = Browserbase(
      
      base_url="http://my.test.server.example.com:8083",
      http_client=DefaultHttpxClient(
          proxies="http://my.test.proxy.example.com",
          transport=httpx.HTTPTransport(local_address="0.0.0.0"),
      ),
  )
  ```

  You can also customize the client on a per-request basis by using `with_options()`:

  ```python
  client.with_options(http_client=DefaultHttpxClient(...))
  ```



  By default the library closes underlying HTTP connections whenever the client is [garbage collected](https://docs.python.org/3/reference/datamodel.html#object.__del__). You can manually close the client using the `.close()` method if desired, or with a context manager that closes when exiting.



  This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:

  1. Changes that only affect static types, without breaking runtime behavior.
  2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals)_.
  3. Changes that we do not expect to impact the vast majority of users in practice.

  We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.

  We are keen for your feedback; please open an [issue](https://www.github.com/browserbase/sdk-python/issues) with questions, bugs, or suggestions.



  If you've upgraded to the latest version but aren't seeing any new features you were expecting then your python environment is likely still using an older version.

  You can determine the version that is being used at runtime with:

  ```py
  import browserbase
  print(browserbase.__version__)
  ```



  Python 3.7 or higher.



  See [the contributing documentation](https://github.com/browserbase/sdk-python/tree/main/./CONTRIBUTING.md).


pkgId: 242a0d7b3a104e622e6da60625b468fa010c38f6a5957a9578e07f25afcb8d35
name: python-browserbase
arch: src
version: 1.0.2
epoch: 0
release: 1
summary: The official Python library for the Browserbase API
url: https://github.com/browserbase/sdk-python
rpm_license: Apache-2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browserbase-1.0.2-1.src.rpm
checksum_type: sha256
description:
  [![PyPI version](https://img.shields.io/pypi/v/browserbase.svg)](https://pypi.org/project/browserbase/)

  The Browserbase Python library provides convenient access to the Browserbase REST API from any Python 3.8+
  application. The library includes type definitions for all request params and response fields,
  and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).

  It is generated with [Stainless](https://www.stainlessapi.com/).



  The REST API documentation can be found on [docs.browserbase.com](https://docs.browserbase.com). The full API of this library can be found in [api.md](https://github.com/browserbase/sdk-python/tree/main/api.md).



  ```sh

  pip install browserbase
  ```



  The full API of this library can be found in [api.md](https://github.com/browserbase/sdk-python/tree/main/api.md).

  ```python
  import os
  from playwright.sync_api import Playwright, sync_playwright
  from browserbase import Browserbase

  BROWSERBASE_API_KEY = os.environ.get("BROWSERBASE_API_KEY")
  BROWSERBASE_PROJECT_ID = os.environ.get("BROWSERBASE_PROJECT_ID")

  bb = Browserbase(
      
      api_key=BROWSERBASE_API_KEY,
  )

  session = client.sessions.create(
      project_id=BROWSERBASE_PROJECT_ID,
  )
  print(session.id)

  def run(playwright: Playwright) -> None:
      
      chromium = playwright.chromium
      browser = chromium.connect_over_cdp(session.connect_url)
      context = browser.contexts[0]
      page = context.pages[0]

      
      page.goto("https://news.ycombinator.com/")
      page_title = page.title()
      assert (
          page_title == "Hacker News"
      ), f"Page title is not 'Hacker News', it is '{page_title}'"
      page.screenshot(path="screenshot.png")

      page.close()
      browser.close()
      print("Done!")


  if __name__ == "__main__":
      with sync_playwright() as playwright:
          run(playwright)
  ```


  See the [examples](https://github.com/browserbase/sdk-python/tree/main/examples) directory for more usage examples.

  > [!NOTE]
  > Running the examples requires [Rye](https://rye.astral.sh/) to be installed.

  To run the examples, clone this repository and run the following commands from the project root (this directory):

  ```bash
  rye sync
  rye run example playwright_basic # replace with the example you want to run
  ```

  > [!NOTE]
  > Make sure you have a `.env` file that matches the [.env.example](https://github.com/browserbase/sdk-python/tree/main/.env.example) file in the root of this repository.



  Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Responses are [Pydantic models](https://docs.pydantic.dev) which also provide helper methods for things like:

  - Serializing back into JSON, `model.to_json()`
  - Converting to a dictionary, `model.to_dict()`

  Typed requests and responses provide autocomplete and documentation within your editor. If you would like to see type errors in VS Code to help catch bugs earlier, set `python.analysis.typeCheckingMode` to `basic`.



  When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `browserbase.APIConnectionError` is raised.

  When the API returns a non-success status code (that is, 4xx or 5xx
  response), a subclass of `browserbase.APIStatusError` is raised, containing `status_code` and `response` properties.

  All errors inherit from `browserbase.APIError`.

  ```python
  import browserbase
  from browserbase import Browserbase

  client = Browserbase()

  try:
      client.sessions.create(
          project_id="your_project_id",
      )
  except browserbase.APIConnectionError as e:
      print("The server could not be reached")
      print(e.__cause__)  # an underlying Exception, likely raised within httpx.
  except browserbase.RateLimitError as e:
      print("A 429 status code was received; we should back off a bit.")
  except browserbase.APIStatusError as e:
      print("Another non-200-range status code was received")
      print(e.status_code)
      print(e.response)
  ```

  Error codes are as followed:

  | Status Code | Error Type                 |
  | ----------- | -------------------------- |
  | 400         | `BadRequestError`          |
  | 401         | `AuthenticationError`      |
  | 403         | `PermissionDeniedError`    |
  | 404         | `NotFoundError`            |
  | 422         | `UnprocessableEntityError` |
  | 429         | `RateLimitError`           |
  | >=500       | `InternalServerError`      |
  | N/A         | `APIConnectionError`       |



  Certain errors are automatically retried 2 times by default, with a short exponential backoff.
  Connection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict,
  429 Rate Limit, and >=500 Internal errors are all retried by default.

  You can use the `max_retries` option to configure or disable retry settings:

  ```python
  from browserbase import Browserbase


  client = Browserbase(
      
      max_retries=0,
  )


  client.with_options(max_retries=5).sessions.create(
      project_id="your_project_id",
  )
  ```



  By default requests time out after 1 minute. You can configure this with a `timeout` option,
  which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/#fine-tuning-the-configuration) object:

  ```python
  from browserbase import Browserbase


  client = Browserbase(
      
      timeout=20.0,
  )


  client = Browserbase(
      timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0),
  )


  client.with_options(timeout=5.0).sessions.create(
      project_id="your_project_id",
  )
  ```

  On timeout, an `APITimeoutError` is thrown.

  Note that requests that time out are [retried twice by default](https://github.com/browserbase/sdk-python/tree/main/#retries).





  We use the standard library [`logging`](https://docs.python.org/3/library/logging.html) module.

  You can enable logging by setting the environment variable `BROWSERBASE_LOG` to `debug`.

  ```shell
  $ export BROWSERBASE_LOG=debug
  ```



  In an API response, a field may be explicitly `null`, or missing entirely; in either case, its value is `None` in this library. You can differentiate the two cases with `.model_fields_set`:

  ```py
  if response.my_field is None:
    if 'my_field' not in response.model_fields_set:
      print('Got json like {}, without a "my_field" key present at all.')
    else:
      print('Got json like {"my_field": null}.')
  ```



  The "raw" Response object can be accessed by prefixing `.with_raw_response.` to any HTTP method call, e.g.,

  ```py
  from browserbase import Browserbase

  client = Browserbase()
  response = client.sessions.with_raw_response.create(
      project_id="your_project_id",
  )
  print(response.headers.get('X-My-Header'))

  session = response.parse()  # get the object that `sessions.create()` would have returned
  print(session.id)
  ```

  These methods return an [`APIResponse`](https://github.com/browserbase/sdk-python/tree/main/src/browserbase/_response.py) object.

  The async client returns an [`AsyncAPIResponse`](https://github.com/browserbase/sdk-python/tree/main/src/browserbase/_response.py) with the same structure, the only difference being `await`able methods for reading the response content.



  The above interface eagerly reads the full response body when you make the request, which may not always be what you want.

  To stream the response body, use `.with_streaming_response` instead, which requires a context manager and only reads the response body once you call `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` or `.parse()`. In the async client, these are async methods.

  ```python
  with client.sessions.with_streaming_response.create(
      project_id="your_project_id",
  ) as response:
      print(response.headers.get("X-My-Header"))

      for line in response.iter_lines():
          print(line)
  ```

  The context manager is required so that the response will reliably be closed.



  This library is typed for convenient access to the documented API.

  If you need to access undocumented endpoints, params, or response properties, the library can still be used.



  To make requests to undocumented endpoints, you can make requests using `client.get`, `client.post`, and other
  http verbs. Options on the client will be respected (such as retries) will be respected when making this
  request.

  ```py
  import httpx

  response = client.post(
      "/foo",
      cast_to=httpx.Response,
      body={"my_param": True},
  )

  print(response.headers.get("x-foo"))
  ```



  If you want to explicitly send an extra param, you can do so with the `extra_query`, `extra_body`, and `extra_headers` request
  options.



  To access undocumented response properties, you can access the extra fields like `response.unknown_prop`. You
  can also get all the extra fields on the Pydantic model as a dict with
  [`response.model_extra`](https://docs.pydantic.dev/latest/api/base_model/#pydantic.BaseModel.model_extra).



  You can directly override the [httpx client](https://www.python-httpx.org/api/#client) to customize it for your use case, including:

  - Support for proxies
  - Custom transports
  - Additional [advanced](https://www.python-httpx.org/advanced/clients/) functionality

  ```python
  from browserbase import Browserbase, DefaultHttpxClient

  client = Browserbase(
      
      base_url="http://my.test.server.example.com:8083",
      http_client=DefaultHttpxClient(
          proxies="http://my.test.proxy.example.com",
          transport=httpx.HTTPTransport(local_address="0.0.0.0"),
      ),
  )
  ```

  You can also customize the client on a per-request basis by using `with_options()`:

  ```python
  client.with_options(http_client=DefaultHttpxClient(...))
  ```



  By default the library closes underlying HTTP connections whenever the client is [garbage collected](https://docs.python.org/3/reference/datamodel.html#object.__del__). You can manually close the client using the `.close()` method if desired, or with a context manager that closes when exiting.



  This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:

  1. Changes that only affect static types, without breaking runtime behavior.
  2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals)_.
  3. Changes that we do not expect to impact the vast majority of users in practice.

  We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.

  We are keen for your feedback; please open an [issue](https://www.github.com/browserbase/sdk-python/issues) with questions, bugs, or suggestions.



  If you've upgraded to the latest version but aren't seeing any new features you were expecting then your python environment is likely still using an older version.

  You can determine the version that is being used at runtime with:

  ```py
  import browserbase
  print(browserbase.__version__)
  ```



  Python 3.8 or higher.



  See [the contributing documentation](https://github.com/browserbase/sdk-python/tree/main/./CONTRIBUTING.md).


pkgId: 61c319c9e760285ae51a3a9d31f9fef0f86c1023dcb49838d54289eaabe2a696
name: python-browserbase
arch: src
version: 1.0.4
epoch: 0
release: 1
summary: The official Python library for the Browserbase API
url: https://github.com/browserbase/sdk-python
rpm_license: Apache-2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browserbase-1.0.4-1.src.rpm
checksum_type: sha256
description:
  [![PyPI version](https://img.shields.io/pypi/v/browserbase.svg)](https://pypi.org/project/browserbase/)

  The Browserbase Python library provides convenient access to the Browserbase REST API from any Python 3.8+
  application. The library includes type definitions for all request params and response fields,
  and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).

  It is generated with [Stainless](https://www.stainlessapi.com/).



  The REST API documentation can be found on [docs.browserbase.com](https://docs.browserbase.com). The full API of this library can be found in [api.md](https://github.com/browserbase/sdk-python/tree/main/api.md).



  ```sh

  pip install browserbase
  ```



  The full API of this library can be found in [api.md](https://github.com/browserbase/sdk-python/tree/main/api.md).

  ```python
  import os
  from playwright.sync_api import Playwright, sync_playwright
  from browserbase import Browserbase

  BROWSERBASE_API_KEY = os.environ.get("BROWSERBASE_API_KEY")
  BROWSERBASE_PROJECT_ID = os.environ.get("BROWSERBASE_PROJECT_ID")

  bb = Browserbase(
      
      api_key=BROWSERBASE_API_KEY,
  )

  session = client.sessions.create(
      project_id=BROWSERBASE_PROJECT_ID,
  )
  print(session.id)

  def run(playwright: Playwright) -> None:
      
      chromium = playwright.chromium
      browser = chromium.connect_over_cdp(session.connect_url)
      context = browser.contexts[0]
      page = context.pages[0]

      
      page.goto("https://news.ycombinator.com/")
      page_title = page.title()
      assert (
          page_title == "Hacker News"
      ), f"Page title is not 'Hacker News', it is '{page_title}'"
      page.screenshot(path="screenshot.png")

      page.close()
      browser.close()
      print("Done!")


  if __name__ == "__main__":
      with sync_playwright() as playwright:
          run(playwright)
  ```


  See the [examples](https://github.com/browserbase/sdk-python/tree/main/examples) directory for more usage examples.

  > [!NOTE]
  > Running the examples requires [Rye](https://rye.astral.sh/) to be installed.

  To run the examples, clone this repository and run the following commands from the project root (this directory):

  ```bash
  rye sync
  rye run example playwright_basic # replace with the example you want to run
  ```

  > [!NOTE]
  > Make sure you have a `.env` file that matches the [.env.example](https://github.com/browserbase/sdk-python/tree/main/.env.example) file in the root of this repository.



  Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Responses are [Pydantic models](https://docs.pydantic.dev) which also provide helper methods for things like:

  - Serializing back into JSON, `model.to_json()`
  - Converting to a dictionary, `model.to_dict()`

  Typed requests and responses provide autocomplete and documentation within your editor. If you would like to see type errors in VS Code to help catch bugs earlier, set `python.analysis.typeCheckingMode` to `basic`.



  When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `browserbase.APIConnectionError` is raised.

  When the API returns a non-success status code (that is, 4xx or 5xx
  response), a subclass of `browserbase.APIStatusError` is raised, containing `status_code` and `response` properties.

  All errors inherit from `browserbase.APIError`.

  ```python
  import browserbase
  from browserbase import Browserbase

  client = Browserbase()

  try:
      client.sessions.create(
          project_id="your_project_id",
      )
  except browserbase.APIConnectionError as e:
      print("The server could not be reached")
      print(e.__cause__)  # an underlying Exception, likely raised within httpx.
  except browserbase.RateLimitError as e:
      print("A 429 status code was received; we should back off a bit.")
  except browserbase.APIStatusError as e:
      print("Another non-200-range status code was received")
      print(e.status_code)
      print(e.response)
  ```

  Error codes are as followed:

  | Status Code | Error Type                 |
  | ----------- | -------------------------- |
  | 400         | `BadRequestError`          |
  | 401         | `AuthenticationError`      |
  | 403         | `PermissionDeniedError`    |
  | 404         | `NotFoundError`            |
  | 422         | `UnprocessableEntityError` |
  | 429         | `RateLimitError`           |
  | >=500       | `InternalServerError`      |
  | N/A         | `APIConnectionError`       |



  Certain errors are automatically retried 2 times by default, with a short exponential backoff.
  Connection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict,
  429 Rate Limit, and >=500 Internal errors are all retried by default.

  You can use the `max_retries` option to configure or disable retry settings:

  ```python
  from browserbase import Browserbase


  client = Browserbase(
      
      max_retries=0,
  )


  client.with_options(max_retries=5).sessions.create(
      project_id="your_project_id",
  )
  ```



  By default requests time out after 1 minute. You can configure this with a `timeout` option,
  which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/#fine-tuning-the-configuration) object:

  ```python
  from browserbase import Browserbase


  client = Browserbase(
      
      timeout=20.0,
  )


  client = Browserbase(
      timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0),
  )


  client.with_options(timeout=5.0).sessions.create(
      project_id="your_project_id",
  )
  ```

  On timeout, an `APITimeoutError` is thrown.

  Note that requests that time out are [retried twice by default](https://github.com/browserbase/sdk-python/tree/main/#retries).





  We use the standard library [`logging`](https://docs.python.org/3/library/logging.html) module.

  You can enable logging by setting the environment variable `BROWSERBASE_LOG` to `info`.

  ```shell
  $ export BROWSERBASE_LOG=info
  ```

  Or to `debug` for more verbose logging.



  In an API response, a field may be explicitly `null`, or missing entirely; in either case, its value is `None` in this library. You can differentiate the two cases with `.model_fields_set`:

  ```py
  if response.my_field is None:
    if 'my_field' not in response.model_fields_set:
      print('Got json like {}, without a "my_field" key present at all.')
    else:
      print('Got json like {"my_field": null}.')
  ```



  The "raw" Response object can be accessed by prefixing `.with_raw_response.` to any HTTP method call, e.g.,

  ```py
  from browserbase import Browserbase

  client = Browserbase()
  response = client.sessions.with_raw_response.create(
      project_id="your_project_id",
  )
  print(response.headers.get('X-My-Header'))

  session = response.parse()  # get the object that `sessions.create()` would have returned
  print(session.id)
  ```

  These methods return an [`APIResponse`](https://github.com/browserbase/sdk-python/tree/main/src/browserbase/_response.py) object.

  The async client returns an [`AsyncAPIResponse`](https://github.com/browserbase/sdk-python/tree/main/src/browserbase/_response.py) with the same structure, the only difference being `await`able methods for reading the response content.



  The above interface eagerly reads the full response body when you make the request, which may not always be what you want.

  To stream the response body, use `.with_streaming_response` instead, which requires a context manager and only reads the response body once you call `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` or `.parse()`. In the async client, these are async methods.

  ```python
  with client.sessions.with_streaming_response.create(
      project_id="your_project_id",
  ) as response:
      print(response.headers.get("X-My-Header"))

      for line in response.iter_lines():
          print(line)
  ```

  The context manager is required so that the response will reliably be closed.



  This library is typed for convenient access to the documented API.

  If you need to access undocumented endpoints, params, or response properties, the library can still be used.



  To make requests to undocumented endpoints, you can make requests using `client.get`, `client.post`, and other
  http verbs. Options on the client will be respected (such as retries) will be respected when making this
  request.

  ```py
  import httpx

  response = client.post(
      "/foo",
      cast_to=httpx.Response,
      body={"my_param": True},
  )

  print(response.headers.get("x-foo"))
  ```



  If you want to explicitly send an extra param, you can do so with the `extra_query`, `extra_body`, and `extra_headers` request
  options.



  To access undocumented response properties, you can access the extra fields like `response.unknown_prop`. You
  can also get all the extra fields on the Pydantic model as a dict with
  [`response.model_extra`](https://docs.pydantic.dev/latest/api/base_model/#pydantic.BaseModel.model_extra).



  You can directly override the [httpx client](https://www.python-httpx.org/api/#client) to customize it for your use case, including:

  - Support for proxies
  - Custom transports
  - Additional [advanced](https://www.python-httpx.org/advanced/clients/) functionality

  ```python
  from browserbase import Browserbase, DefaultHttpxClient

  client = Browserbase(
      
      base_url="http://my.test.server.example.com:8083",
      http_client=DefaultHttpxClient(
          proxies="http://my.test.proxy.example.com",
          transport=httpx.HTTPTransport(local_address="0.0.0.0"),
      ),
  )
  ```

  You can also customize the client on a per-request basis by using `with_options()`:

  ```python
  client.with_options(http_client=DefaultHttpxClient(...))
  ```



  By default the library closes underlying HTTP connections whenever the client is [garbage collected](https://docs.python.org/3/reference/datamodel.html#object.__del__). You can manually close the client using the `.close()` method if desired, or with a context manager that closes when exiting.



  This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:

  1. Changes that only affect static types, without breaking runtime behavior.
  2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals)_.
  3. Changes that we do not expect to impact the vast majority of users in practice.

  We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.

  We are keen for your feedback; please open an [issue](https://www.github.com/browserbase/sdk-python/issues) with questions, bugs, or suggestions.



  If you've upgraded to the latest version but aren't seeing any new features you were expecting then your python environment is likely still using an older version.

  You can determine the version that is being used at runtime with:

  ```py
  import browserbase
  print(browserbase.__version__)
  ```



  Python 3.8 or higher.



  See [the contributing documentation](https://github.com/browserbase/sdk-python/tree/main/./CONTRIBUTING.md).


pkgId: 8e86b0bec905b3463744dec58ac736fddba7df8c04631dbfa11c78625478a6fa
name: python-browsercookie
arch: src
version: 0.7.9
epoch: 0
release: 1
url: https://github.com/richardpenman/browsercookie
rpm_license: lgpl
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browsercookie-0.7.9-1.src.rpm
checksum_type: sha256
summary:
  Loads cookies from your browser into a cookiejar object so can download with urllib and other libraries the same content you see in the web browser.

description:
  The **browsercookie** module loads cookies used by your web browser
  into a cookiejar object. This can be useful if you want to use python to
  download the same content you see in the web browser without needing to
  login.


pkgId: ad5312af02be89422f21b3f54c423dd17c0eacdccf84c82a7acae9a53a478ff1
name: python-browserdebuggertools
arch: src
version: 6.0.3
epoch: 0
release: 1
summary: A client which calls remote web browser debugger methods
url: https://github.com/scivisum/browser-debugger-tools
rpm_license: GNU General Public License v3
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browserdebuggertools-6.0.3-1.src.rpm
checksum_type: sha256
description:
  [![CirclCI](https://circleci.com/gh/scivisum/browser-debugger-tools.svg?style=svg)](https://app.circleci.com/pipelines/github/scivisum/browser-debugger-tools?branch=master)
  [![PyPI](https://img.shields.io/pypi/v/browserdebuggertools.svg?style=flat-square)](https://pypi.python.org/pypi/browserdebuggertools)
  ![Python](https://img.shields.io/pypi/pyversions/browserdebuggertools.svg?style=flat-square)
  ![License](https://img.shields.io/pypi/l/browserdebuggertools.svg?style=flat-square)

  The purpose is to provide a python client to connect to the debugger tools of a web-browser.

  **Currently supports** connecting to **Google-Chrome/Chromium** over the devtools protocol, via a wrapped websockets client. **Feel free to extend and add support for other browsers** as required.

  For improved performance, install the wsaccel python lib https://pypi.org/project/wsaccel/



  Start Google-Chrome, passing a remote debugger port argument, for example on Ubuntu:
  ```
  $ google-chrome-stable --remote-debugging-port=9899
  ```

  In a python console, you can connect to the remote debugging port and enable the Page domain.
  ```
  >> devtools_client = ChromeInterface(9899, domains={"Page": {}})
  ```

  The client provides some devtools interface methods, for example:
  ```
  >> with devtools_client.set_timeout(10):
     ... devtools_client.take_screenshot("/tmp/screenshot.png")
  ```

  Or more generally you can call remote methods according to the devtools protocol spec (https://chromedevtools.github.io/devtools-protocol/tot/Network), for example
  ```
  >> devtools_client.execute(domain="Network", method="enable")
  >> devtools_client.execute("Network", "setUserAgentOverride", {"userAgent": "Test"})
  ````


pkgId: 167e1f4b2dac5f761180a3f67b79ac862fc717ed49f20981e3c1da040ab32c82
name: python-browserexport
arch: src
version: 0.4.2
epoch: 0
release: 1
summary: save and merge browser history and metadata from different browsers
url: https://github.com/seanbreckenridge/browserexport
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browserexport-0.4.2-1.src.rpm
checksum_type: sha256
description:
  [![PyPi version](https://img.shields.io/pypi/v/browserexport.svg)](https://pypi.python.org/pypi/browserexport) [![Python 3.8|3.9|3.10|3.11|3.12](https://img.shields.io/pypi/pyversions/browserexport.svg)](https://pypi.python.org/pypi/browserexport) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)

  - [Supported Browsers](#supported-browsers)
  - [Install](#install)
  - [Usage](#usage)
    - [`save`](#save)
    - [`inspect`/`merge`](#inspectmerge)
  - [Serializing to JSON](#json)
  - [Shell Completion](#shell-completion)
  - [Usage with HPI](#hpi)
  - [Library Usage](#library-usage)
  - [Comparisons with promnesia](#comparisons-with-promnesia)
  - [Contributing](#contributing)
    - [Development](#development)
    - [Testing](#testing)

  This:

  - locates and backs up browser history by copying the underlying database files to some directory you specify
  - can identify and parse the resulting database files into some common schema:

  ```
  Visit:
    url: the url
    dt: datetime (when you went to this page)
    metadata:
      title: the <title> for this page
      description: the <meta description> tag from this page
      preview_image: 'main image' for this page, often opengraph/favicon
      duration: how long you were on this page
  ```

  `metadata` is dependent on the data available in the browser (e.g. firefox has preview images, chrome has duration, but not vice versa)



  This currently supports:

  - [Firefox](https://www.mozilla.org/en-US/firefox/new/)
    - [Waterfox](https://www.waterfox.net/)
    - [Floorp](https://floorp.app/)
    - [Librewolf](https://librewolf.net/)
    - Firefox Android (pre-2020 schema and current [Fenix](https://github.com/mozilla-mobile/fenix))
  - [Chrome](https://www.google.com/chrome/)
    - [Chromium](https://www.chromium.org/chromium-projects/)
    - [Brave](https://brave.com/)
    - [Vivaldi](https://vivaldi.com/)
    - [Opera](https://www.opera.com/)
    - [Arc](https://arc.net/)
    - [Edge](https://www.microsoft.com/edge) (and [Dev Channel](https://www.microsoft.com/edge/download/insider))
  - [Safari](https://www.apple.com/safari/)
  - [Palemoon](https://www.palemoon.org/)

  This can probably extract visits from other Firefox/Chromium-based browsers, but it doesn't know how to locate them to `save` them



  `python3 -m pip install --user browserexport`

  Requires `python3.7+`





  ```
  Usage: browserexport save [OPTIONS]

    Backs up a current browser database file

  Options:
    -b, --browser
        [chrome | firefox | opera | safari | brave | waterfox |
        librewolf | floorp | chromium | vivaldi | palemoon | arc |
        edge | edgedev]
                                    Browser name to backup history for
    --pattern TEXT                  Pattern for the resulting timestamped filename, should include an
                                    str.format replacement placeholder for the date [default:
                                    browser_name-{}.extension]
    -p, --profile TEXT              Use to pick the correct profile to back up. If unspecified, will assume a
                                    single profile  [default: *]
    --path FILE                     Specify a direct path to a database to back up
    -t, --to DIRECTORY              Directory to store backup to. Pass '-' to print database to STDOUT
                                    [required]
    -h, --help                      Show this message and exit.
  ```

  Must specify one of `--browser`, or `--path`

  After your browser history reaches a certain size, browsers typically remove old history over time, so I'd recommend backing up your history periodically, like:

  ```shell
  $ browserexport save -b firefox --to ~/data/browsing
  $ browserexport save -b chrome --to ~/data/browsing
  $ browserexport save -b safari --to ~/data/browsing
  ```

  That copies the sqlite databases which contains your history `--to` some backup directory.

  If a browser you want to backup is Firefox/Chrome-like (so this would be able to parse it), but this doesn't support locating it yet, you can directly back it up with the `--path` flag:

  ```shell
  $ browserexport save --path ~/.somebrowser/profile/places.sqlite \
    --to ~/data/browsing
  ```

  The `--pattern` argument can be used to change the resulting filename for the browser, e.g. `--pattern 'places-{}.sqlite'` or `--pattern "$(uname)-{}.sqlite"`. The `{}` is replaced by the browser name.

  Feel free to create an issue/contribute a [browser](./browserexport/browsers/) file to locate the browser if this doesn't support some browser you use.

  Can pass the `--debug` flag to show [`sqlite_backup`](https://github.com/seanbreckenridge/sqlite_backup) logs

  ```
  $ browserexport --debug save -b firefox --to .
  [D 220202 10:10:22 common:87] Glob /home/sean/.mozilla/firefox with */places.sqlite (non recursive) matched [PosixPath('/home/sean/.mozilla/firefox/ew9cqpqe.dev-edition-default/places.sqlite')]
  [I 220202 10:10:22 save:18] backing up /home/sean/.mozilla/firefox/ew9cqpqe.dev-edition-default/places.sqlite to /home/sean/Repos/browserexport/firefox-20220202181022.sqlite
  [D 220202 10:10:22 core:110] Source database files: '['/tmp/tmpcn6gpj1v/places.sqlite', '/tmp/tmpcn6gpj1v/places.sqlite-wal']'
  [D 220202 10:10:22 core:111] Temporary Destination database files: '['/tmp/tmpcn6gpj1v/places.sqlite', '/tmp/tmpcn6gpj1v/places.sqlite-wal']'
  [D 220202 10:10:22 core:64] Copied from '/home/sean/.mozilla/firefox/ew9cqpqe.dev-edition-default/places.sqlite' to '/tmp/tmpcn6gpj1v/places.sqlite' successfully; copied without file changing: True
  [D 220202 10:10:22 core:64] Copied from '/home/sean/.mozilla/firefox/ew9cqpqe.dev-edition-default/places.sqlite-wal' to '/tmp/tmpcn6gpj1v/places.sqlite-wal' successfully; copied without file changing: True
  [D 220202 10:10:22 core:230] Running backup, from '/tmp/tmpcn6gpj1v/places.sqlite' to '/home/sean/Repos/browserexport/firefox-20220202181022.sqlite'
  [D 220202 10:10:22 save:14] Copied 1840 of 1840 database pages...
  [D 220202 10:10:22 core:246] Executing 'wal_checkpoint(TRUNCATE)' on destination '/home/sean/Repos/browserexport/firefox-20220202181022.sqlite'
  ```

  For Firefox Android [Fenix](https://github.com/mozilla-mobile/fenix/), the database has to be manually backed up (probably from a rooted phone using [`termux`](https://termux.dev/en/)) from `data/data/org.mozilla.fenix/files/places.sqlite`.



  These work very similarly, `inspect` is for a single database, `merge` is for multiple databases.

  ```
  Usage: browserexport merge [OPTIONS] SQLITE_DB...

    Extracts visits from multiple sqlite databases

    Provide multiple sqlite databases as positional arguments, e.g.:
    browserexport merge ~/data/firefox/*.sqlite

    Drops you into a REPL to access the data

    Pass '-' to read from STDIN

  Options:
    -s, --stream  Stream JSON objects instead of printing a JSON list
    -j, --json    Print result to STDOUT as JSON
    -h, --help    Show this message and exit.
  ```

  As an example:

  ```
  browserexport --debug merge ~/data/firefox/* ~/data/chrome/*
  [D 210417 21:12:18 merge:38] merging information from 24 sources...
  [D 210417 21:12:18 parse:19] Reading visits from /home/sean/data/firefox/places-20200828223058.sqlite...
  [D 210417 21:12:18 common:40] Chrome: Running detector query 'SELECT * FROM keyword_search_terms'
  [D 210417 21:12:18 common:40] Firefox: Running detector query 'SELECT * FROM moz_meta'
  [D 210417 21:12:18 parse:22] Detected as Firefox
  [D 210417 21:12:19 parse:19] Reading visits from /home/sean/data/firefox/places-20201010031025.sqlite...
  [D 210417 21:12:19 common:40] Chrome: Running detector query 'SELECT * FROM keyword_search_terms'
  ....
  [D 210417 21:12:48 common:40] Firefox: Running detector query 'SELECT * FROM moz_meta'
  [D 210417 21:12:48 common:40] Safari: Running detector query 'SELECT * FROM history_tombstones'
  [D 210417 21:12:48 parse:22] Detected as Safari
  [D 210417 21:12:48 merge:51] Summary: removed 3001879 duplicates...
  [D 210417 21:12:48 merge:52] Summary: returning 334490 visit entries...

  Use vis to interact with the data

  [1] ...
  ```

  You can also read from STDIN, so this can be used in conjunction with `save`, to merge databases you've backed up and combine your current browser history:

  ```bash
  browserexport save -b firefox -t - | browserexport merge --json --stream - ~/data/browsing/* >all.jsonl
  ```

  Or, to just print the demo for your current browser history:

  ```bash
  $ browserexport save -b firefox -t - | browserexport inspect -
  Demo: Your most common sites....
   [('github.com', 21033),
    ...
  ```

  Or, use [process substitution](https://tldp.org/LDP/abs/html/process-sub.html) to save multiple dbs in parallel and then merge them:

  ```bash
  $ browserexport merge <(browserexport save -b firefox -t -) <(browserexport save -b chrome -t -)
  ```

  Logs are hidden by default. To show the debug logs set `export BROWSEREXPORT_LOGS=10` (uses [logging levels](https://docs.python.org/3/library/logging.html#logging-levels)) or pass the `--debug` flag.



  To dump all that info to JSON:

  ```bash
  $ browserexport merge --json ~/data/browsing/*.sqlite > ./history.json
  du -h history.json
  67M     history.json
  ```

  Or, to create a quick searchable interface, using [`jq`](https://github.com/stedolan/jq) and [`fzf`](https://github.com/junegunn/fzf):

  `browserexport merge -j --stream ~/data/browsing/*.sqlite | jq '"\(.url)|\(.metadata.description)"' | awk '!seen[$0]++' | fzf`

  Merged files like `history.json` can also be used as inputs files themselves, this reads those by mapping the JSON onto the `Visit` schema directly.

  In addition to `.json` files, this can parse `.jsonl` ([JSON lines](http://jsonlines.org/)) files, which are files which contain newline delimited JSON objects. This allows you to parse JSON objects one at a time, instead of loading the entire file into memory. The `.jsonl` file can be generated with the `--stream` flag:

  ```
  browserexport merge --stream --json ~/data/browsing/*.sqlite > ./history.jsonl
  ```

  _Additionally_, this can parse compressed JSON/JSONL files (using [kompress](https://github.com/karlicoss/kompress/)): `.xz`, `.zip`, `.lz4`, `.zstd`, `.zst`, `.tar.gz`, `.gz`

  For example, you could do:

  ```bash
  browserexport merge --stream --json ~/data/browsing/*.sqlite | gzip --best > ./history.jsonl.gz

  browserexport --debug inspect ./history.jsonl.gz
  ```

  If you don't care about keeping the raw databases for any other auxiliary info like form, bookmark data, or [from_visit](https://github.com/seanbreckenridge/browserexport/issues/30) info and just want the URL, visit date and metadata, you could use `merge` to periodically merge the bulky `.sqlite` files into a gzipped JSONL dump to reduce storage space, and improve parsing speed:

  ```bash

  rsync -Pavh ~/data/browsing ~/.cache/browsing

  browserexport --debug merge --json --stream ~/data/browsing/* > '/tmp/browsing.jsonl'
  gzip '/tmp/browsing.jsonl'

  browserexport --debug inspect '/tmp/browsing.jsonl.gz'

  rm ~/data/browsing/*

  mv /tmp/browsing.jsonl.gz ~/data/browsing
  ```

  I do this every couple months with a script [here](https://github.com/seanbreckenridge/bleanser/blob/master/bin/merge-browser-history), and then sync my old databases to a harddrive for more long-term storage



  This uses `click`, which supports [shell completion](https://click.palletsprojects.com/en/8.1.x/options/) for `bash`, `zsh` and `fish`. To generate the completion on startup, put one of the following in your shell init file (`.bashrc`/`.zshrc` etc)

  ```bash
  eval "$(_BROWSEREXPORT_COMPLETE=bash_source browserexport)" # bash
  eval "$(_BROWSEREXPORT_COMPLETE=zsh_source browserexport)" # zsh
  _BROWSEREXPORT_COMPLETE=fish_source browserexport | source  # fish
  ```

  Instead of `eval`ing, you could of course save the generated completion to a file and/or lazy load it in your shell config, see [bash completion docs](https://github.com/scop/bash-completion/blob/master/README.md#faq), [zsh functions](https://zsh.sourceforge.io/Doc/Release/Functions.html), [fish completion docs](https://fishshell.com/docs/current/completions.html). For example for `zsh` that might look like:

  ```bash
  mkdir -p ~/.config/zsh/functions/
  _BROWSEREXPORT_COMPLETE=zsh_source browserexport > ~/.config/zsh/functions/_browserexport
  ```

  ```bash


  fpath=(~/.config/zsh/functions $fpath)
  autoload -Uz compinit && compinit
  ```



  If you want to cache the merged results, this has a [module in HPI](https://github.com/karlicoss/HPI) which handles locating/caching and querying the results. See [setup](https://github.com/karlicoss/HPI/blob/master/doc/SETUP.org#install-main-hpi-package) and [module setup](https://github.com/karlicoss/HPI/blob/master/doc/MODULES.org#mybrowser).

  That uses [cachew](https://github.com/karlicoss/cachew) to automatically cache the merged results, recomputing whenever you backup new databases

  As a few examples:

  ```sh
  ✅ OK  : my.browser.all
  ✅     - stats: {'history': {'count': 1091091, 'last': datetime.datetime(2023, 2, 11, 1, 12, 37, 302883, tzinfo=datetime.timezone.utc)}}
  ✅ OK  : my.browser.export
  ✅     - stats: {'history': {'count': 1090850, 'last': datetime.datetime(2023, 2, 11, 4, 34, 12, 985488, tzinfo=datetime.timezone.utc)}}
  ✅ OK  : my.browser.active_browser
  ✅     - stats: {'history': {'count': 270363, 'last': datetime.datetime(2023, 2, 11, 22, 26, 24, 887722, tzinfo=datetime.timezone.utc)}}
  ```

  ```sh

  $ hpi query my.browser.all --order-type datetime --after '2022-01-01 00:00:00' --before '2022-01-31 23:59:59' | jq length
  50432

  $ hpi query my.browser.all --recent 4w -s | jq .url | grep 'github.com' -c
  16357
  ```



  To save databases:

  ```python
  from browserexport.save import backup_history
  backup_history("firefox", "~/data/backups")

  from browserexport.browsers.all import Firefox
  backup_history(Firefox, "~/data/backups")
  ```

  To merge/read visits from databases:

  ```python
  from browserexport.merge import read_and_merge
  read_and_merge(["/path/to/database", "/path/to/second/database", "..."])
  ```

  You can also use [`sqlite_backup`](https://github.com/seanbreckenridge/sqlite_backup) to copy your current browser history into a sqlite connection in memory, as a `sqlite3.Connection`

  ```python
  from browserexport.browsers.all import Firefox
  from browserexport.parse import read_visits
  from sqlite_backup import sqlite_backup

  db_in_memory = sqlite_backup(Firefox.locate_database())
  visits = list(read_visits(db_in_memory))


  from browserexport.merge import merge_visits, read_and_merge
  merged = list(merge_visits([
      visits,
      read_and_merge(["/path/to/another/database.sqlite", "..."]),
  ]))
  ```

  If this doesn't support a browser and you wish to quickly extend without maintaining a fork (or contributing back to this repo), you can pass a `Browser` implementation (see [browsers/all.py](./browserexport/browsers/all.py) and [browsers/common.py](./browserexport/browsers/common.py) for more info) to `browserexport.parse.read_visits` or programmatically override/add your own browsers as part of the [`browserexport.browsers` namespace package](https://github.com/seanbreckenridge/browserexport/blob/0705629e1dc87fe47d6f731018d26dc3720cf2fe/browserexport/browsers/all.py#L15-L24)



  A lot of the initial queries/ideas here were taken from [promnesia](https://github.com/karlicoss/promnesia) and the [`browser_history.py`](https://github.com/karlicoss/promnesia/blob/0e1e9a1ccd1f07b2a64336c18c7f41ca24fcbcd4/scripts/browser_history.py) script, but creating a package here allows its to be more extendible, e.g. allowing you to override/locate additional databases.

  TLDR on promnesia: lets you explore your browsing history in context: where you encountered it, in chat, on Twitter, on Reddit, or just in one of the text files on your computer. This is unlike most modern browsers, where you can only see when you visited the link.

  Since [promnesia #375](https://github.com/karlicoss/promnesia/pull/375), `browserexport` is used in [promnesia](https://github.com/karlicoss/promnesia) in the `browser.py` file (to read any of the supported databases here from disk), see [setup](https://github.com/karlicoss/promnesia#setup) and [the browser source quickstart](https://github.com/karlicoss/promnesia/blob/master/doc/SOURCES.org#browser) in the instructions for more



  Clone the repository and [optionally] create a [virtual environment](https://docs.python.org/3/library/venv.html) to do your work in.

  ```bash
  git clone https://github.com/seanbreckenridge/browserexport
  cd ./browserexport

  python -m virtualenv .venv  # python3 -m pip install virtualenv if missing
  source .venv/bin/activate
  ```



  To install, run:

  ```bash
  python3 -m pip install '.[testing]'
  ```

  If running in a virtual environment, `pip` will automatically install dependencies into your virtual environment. If running `browserexport` happens to use the globally installed `browserexport` instead, you can use `python3 -m browserexport` to ensure its using the version in your virtual environment.

  After making changes to the code, reinstall by running `pip install .`, and then test with `browserexport` or `python3 -m browserexport`



  While developing, you can run tests with:

  ```bash
  pytest
  flake8 ./browserexport
  mypy ./browserexport

  python3 -m pip install black
  find browserexport tests -name '*.py' -exec python3 -m black {} +
  ```


pkgId: ea23b1c1af32e8382092ca6e281206010f218767b9ecdec11e7c74b062db906d
name: python-browserexport
arch: src
version: 0.4.3
epoch: 0
release: 1
summary: save and merge browser history and metadata from different browsers
url: https://github.com/purarue/browserexport
rpm_license: MIT
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browserexport-0.4.3-1.src.rpm
checksum_type: sha256
description:
  [![PyPi version](https://img.shields.io/pypi/v/browserexport.svg)](https://pypi.python.org/pypi/browserexport) [![Python 3.9|3.10|3.11|3.12|3.13](https://img.shields.io/pypi/pyversions/browserexport.svg)](https://pypi.python.org/pypi/browserexport) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)

  - [Supported Browsers](#supported-browsers)
  - [Install](#install)
  - [Usage](#usage)
    - [`save`](#save)
    - [`inspect`/`merge`](#inspectmerge)
  - [Serializing to JSON](#json)
  - [Shell Completion](#shell-completion)
  - [Usage with HPI](#hpi)
  - [Library Usage](#library-usage)
  - [Comparisons with promnesia](#comparisons-with-promnesia)
  - [Contributing](#contributing)
    - [Development](#development)
    - [Testing](#testing)

  This:

  - locates and backs up browser history by copying the underlying database files to some directory you specify
  - can identify and parse the resulting database files into some common schema:

  ```
  Visit:
    url: the url
    dt: datetime (when you went to this page)
    metadata:
      title: the <title> for this page
      description: the <meta description> tag from this page
      preview_image: 'main image' for this page, often opengraph/favicon
      duration: how long you were on this page
  ```

  `metadata` is dependent on the data available in the browser (e.g. firefox has preview images, chrome has duration, but not vice versa)



  This currently supports:

  - [Firefox](https://www.mozilla.org/en-US/firefox/new/)
    - [Waterfox](https://www.waterfox.net/)
    - [Floorp](https://floorp.app/)
    - [Librewolf](https://librewolf.net/)
    - Firefox Android (pre-2020 schema and current [Fenix](https://github.com/mozilla-mobile/fenix))
  - [Chrome](https://www.google.com/chrome/)
    - [Chromium](https://www.chromium.org/chromium-projects/)
    - [Brave](https://brave.com/)
    - [Vivaldi](https://vivaldi.com/)
    - [Opera](https://www.opera.com/)
    - [Arc](https://arc.net/)
    - [Edge](https://www.microsoft.com/edge) (and [Dev Channel](https://www.microsoft.com/edge/download/insider))
  - [Safari](https://www.apple.com/safari/)
  - [Palemoon](https://www.palemoon.org/)

  This can probably extract visits from other Firefox/Chromium-based browsers, but it doesn't know how to locate them to `save` them



  `python3 -m pip install --user browserexport`

  Requires `python3.9+`





  ```
  Usage: browserexport save [OPTIONS]

    Backs up a current browser database file

  Options:
    -b, --browser
        [chrome | firefox | opera | safari | brave | waterfox |
        librewolf | floorp | chromium | vivaldi | palemoon | arc |
        edge | edgedev]
                                    Browser name to backup history for
    --pattern TEXT                  Pattern for the resulting timestamped filename, should include an
                                    str.format replacement placeholder for the date [default:
                                    browser_name-{}.extension]
    -p, --profile TEXT              Use to pick the correct profile to back up. If unspecified, will assume a
                                    single profile  [default: *]
    --path FILE                     Specify a direct path to a database to back up
    -t, --to DIRECTORY              Directory to store backup to. Pass '-' to print database to STDOUT
                                    [required]
    -h, --help                      Show this message and exit.
  ```

  Must specify one of `--browser`, or `--path`

  After your browser history reaches a certain size, browsers typically remove old history over time, so I'd recommend backing up your history periodically, like:

  ```shell
  $ browserexport save -b firefox --to ~/data/browsing
  $ browserexport save -b chrome --to ~/data/browsing
  $ browserexport save -b safari --to ~/data/browsing
  ```

  That copies the sqlite databases which contains your history `--to` some backup directory.

  If a browser you want to backup is Firefox/Chrome-like (so this would be able to parse it), but this doesn't support locating it yet, you can directly back it up with the `--path` flag:

  ```shell
  $ browserexport save --path ~/.somebrowser/profile/places.sqlite \
    --to ~/data/browsing
  ```

  The `--pattern` argument can be used to change the resulting filename for the browser, e.g. `--pattern 'places-{}.sqlite'` or `--pattern "$(uname)-{}.sqlite"`. The `{}` is replaced by the browser name.

  Feel free to create an issue/contribute a [browser](./browserexport/browsers/) file to locate the browser if this doesn't support some browser you use.

  Can pass the `--debug` flag to show [`sqlite_backup`](https://github.com/purarue/sqlite_backup) logs

  ```
  $ browserexport --debug save -b firefox --to .
  [D 220202 10:10:22 common:87] Glob /home/username/.mozilla/firefox with */places.sqlite (non recursive) matched [PosixPath('/home/username/.mozilla/firefox/ew9cqpqe.dev-edition-default/places.sqlite')]
  [I 220202 10:10:22 save:18] backing up /home/username/.mozilla/firefox/ew9cqpqe.dev-edition-default/places.sqlite to /home/username/Repos/browserexport/firefox-20220202181022.sqlite
  [D 220202 10:10:22 core:110] Source database files: '['/tmp/tmpcn6gpj1v/places.sqlite', '/tmp/tmpcn6gpj1v/places.sqlite-wal']'
  [D 220202 10:10:22 core:111] Temporary Destination database files: '['/tmp/tmpcn6gpj1v/places.sqlite', '/tmp/tmpcn6gpj1v/places.sqlite-wal']'
  [D 220202 10:10:22 core:64] Copied from '/home/username/.mozilla/firefox/ew9cqpqe.dev-edition-default/places.sqlite' to '/tmp/tmpcn6gpj1v/places.sqlite' successfully; copied without file changing: True
  [D 220202 10:10:22 core:64] Copied from '/home/username/.mozilla/firefox/ew9cqpqe.dev-edition-default/places.sqlite-wal' to '/tmp/tmpcn6gpj1v/places.sqlite-wal' successfully; copied without file changing: True
  [D 220202 10:10:22 core:230] Running backup, from '/tmp/tmpcn6gpj1v/places.sqlite' to '/home/username/Repos/browserexport/firefox-20220202181022.sqlite'
  [D 220202 10:10:22 save:14] Copied 1840 of 1840 database pages...
  [D 220202 10:10:22 core:246] Executing 'wal_checkpoint(TRUNCATE)' on destination '/home/username/Repos/browserexport/firefox-20220202181022.sqlite'
  ```

  For Firefox Android [Fenix](https://github.com/mozilla-mobile/fenix/), the database has to be manually backed up (probably from a rooted phone using [`termux`](https://termux.dev/en/)) from `data/data/org.mozilla.fenix/files/places.sqlite`.



  These work very similarly, `inspect` is for a single database, `merge` is for multiple databases.

  ```
  Usage: browserexport merge [OPTIONS] SQLITE_DB...

    Extracts visits from multiple sqlite databases

    Provide multiple sqlite databases as positional arguments, e.g.:
    browserexport merge ~/data/firefox/*.sqlite

    Drops you into a REPL to access the data

    Pass '-' to read from STDIN

  Options:
    -s, --stream  Stream JSON objects instead of printing a JSON list
    -j, --json    Print result to STDOUT as JSON
    -h, --help    Show this message and exit.
  ```

  As an example:

  ```
  browserexport --debug merge ~/data/firefox/* ~/data/chrome/*
  [D 210417 21:12:18 merge:38] merging information from 24 sources...
  [D 210417 21:12:18 parse:19] Reading visits from /home/username/data/firefox/places-20200828223058.sqlite...
  [D 210417 21:12:18 common:40] Chrome: Running detector query 'SELECT * FROM keyword_search_terms'
  [D 210417 21:12:18 common:40] Firefox: Running detector query 'SELECT * FROM moz_meta'
  [D 210417 21:12:18 parse:22] Detected as Firefox
  [D 210417 21:12:19 parse:19] Reading visits from /home/username/data/firefox/places-20201010031025.sqlite...
  [D 210417 21:12:19 common:40] Chrome: Running detector query 'SELECT * FROM keyword_search_terms'
  ....
  [D 210417 21:12:48 common:40] Firefox: Running detector query 'SELECT * FROM moz_meta'
  [D 210417 21:12:48 common:40] Safari: Running detector query 'SELECT * FROM history_tombstones'
  [D 210417 21:12:48 parse:22] Detected as Safari
  [D 210417 21:12:48 merge:51] Summary: removed 3001879 duplicates...
  [D 210417 21:12:48 merge:52] Summary: returning 334490 visit entries...

  Use vis to interact with the data

  [1] ...
  ```

  You can also read from STDIN, so this can be used in conjunction with `save`, to merge databases you've backed up and combine your current browser history:

  ```bash
  browserexport save -b firefox -t - | browserexport merge --json --stream - ~/data/browsing/* >all.jsonl
  ```

  Or, use [process substitution](https://tldp.org/LDP/abs/html/process-sub.html) to save multiple dbs in parallel and then merge them:

  ```bash
  $ browserexport merge <(browserexport save -b firefox -t -) <(browserexport save -b chrome -t -)
  ```

  Logs are hidden by default. To show the debug logs set `export BROWSEREXPORT_LOGS=10` (uses [logging levels](https://docs.python.org/3/library/logging.html#logging-levels)) or pass the `--debug` flag.



  To dump all that info to JSON:

  ```bash
  $ browserexport merge --json ~/data/browsing/*.sqlite > ./history.json
  du -h history.json
  67M     history.json
  ```

  Or, to create a quick searchable interface, using [`jq`](https://github.com/stedolan/jq) and [`fzf`](https://github.com/junegunn/fzf):

  `browserexport merge -j --stream ~/data/browsing/*.sqlite | jq '"\(.url)|\(.metadata.description)"' | awk '!seen[$0]++' | fzf`

  Merged files like `history.json` can also be used as inputs files themselves, this reads those by mapping the JSON onto the `Visit` schema directly.

  In addition to `.json` files, this can parse `.jsonl` ([JSON lines](http://jsonlines.org/)) files, which are files which contain newline delimited JSON objects. This allows you to parse JSON objects one at a time, instead of loading the entire file into memory. The `.jsonl` file can be generated with the `--stream` flag:

  ```
  browserexport merge --stream --json ~/data/browsing/*.sqlite > ./history.jsonl
  ```

  _Additionally_, this can parse compressed JSON/JSONL files (using [kompress](https://github.com/karlicoss/kompress/)): `.xz`, `.zip`, `.lz4`, `.zstd`, `.zst`, `.tar.gz`, `.gz`

  For example, you could do:

  ```bash
  browserexport merge --stream --json ~/data/browsing/*.sqlite | gzip --best > ./history.jsonl.gz

  browserexport --debug inspect ./history.jsonl.gz
  ```

  If you don't care about keeping the raw databases for any other auxiliary info like form, bookmark data, or [from_visit](https://github.com/purarue/browserexport/issues/30) info and just want the URL, visit date and metadata, you could use `merge` to periodically merge the bulky `.sqlite` files into a gzipped JSONL dump to reduce storage space, and improve parsing speed:

  ```bash

  rsync -Pavh ~/data/browsing ~/.cache/browsing

  browserexport --debug merge --json --stream ~/data/browsing/* > '/tmp/browsing.jsonl'
  gzip '/tmp/browsing.jsonl'

  browserexport --debug inspect '/tmp/browsing.jsonl.gz'

  rm ~/data/browsing/*

  mv /tmp/browsing.jsonl.gz ~/data/browsing
  ```

  I do this every couple months with a script [here](https://github.com/purarue/bleanser/blob/master/bin/merge-browser-history), and then sync my old databases to a harddrive for more long-term storage



  This uses `click`, which supports [shell completion](https://click.palletsprojects.com/en/8.1.x/options/) for `bash`, `zsh` and `fish`. To generate the completion on startup, put one of the following in your shell init file (`.bashrc`/`.zshrc` etc)

  ```bash
  eval "$(_BROWSEREXPORT_COMPLETE=bash_source browserexport)" # bash
  eval "$(_BROWSEREXPORT_COMPLETE=zsh_source browserexport)" # zsh
  _BROWSEREXPORT_COMPLETE=fish_source browserexport | source  # fish
  ```

  Instead of `eval`ing, you could of course save the generated completion to a file and/or lazy load it in your shell config, see [bash completion docs](https://github.com/scop/bash-completion/blob/master/README.md#faq), [zsh functions](https://zsh.sourceforge.io/Doc/Release/Functions.html), [fish completion docs](https://fishshell.com/docs/current/completions.html). For example for `zsh` that might look like:

  ```bash
  mkdir -p ~/.config/zsh/functions/
  _BROWSEREXPORT_COMPLETE=zsh_source browserexport > ~/.config/zsh/functions/_browserexport
  ```

  ```bash


  fpath=(~/.config/zsh/functions $fpath)
  autoload -Uz compinit && compinit
  ```



  If you want to cache the merged results, this has a [module in HPI](https://github.com/karlicoss/HPI) which handles locating/caching and querying the results. See [setup](https://github.com/karlicoss/HPI/blob/master/doc/SETUP.org#install-main-hpi-package) and [module setup](https://github.com/karlicoss/HPI/blob/master/doc/MODULES.org#mybrowser).

  That uses [cachew](https://github.com/karlicoss/cachew) to automatically cache the merged results, recomputing whenever you backup new databases

  As a few examples:

  ```sh
  ✅ OK  : my.browser.all
  ✅     - stats: {'history': {'count': 1091091, 'last': datetime.datetime(2023, 2, 11, 1, 12, 37, 302883, tzinfo=datetime.timezone.utc)}}
  ✅ OK  : my.browser.export
  ✅     - stats: {'history': {'count': 1090850, 'last': datetime.datetime(2023, 2, 11, 4, 34, 12, 985488, tzinfo=datetime.timezone.utc)}}
  ✅ OK  : my.browser.active_browser
  ✅     - stats: {'history': {'count': 270363, 'last': datetime.datetime(2023, 2, 11, 22, 26, 24, 887722, tzinfo=datetime.timezone.utc)}}
  ```

  ```sh

  $ hpi query my.browser.all --order-type datetime --after '2022-01-01 00:00:00' --before '2022-01-31 23:59:59' | jq length
  50432

  $ hpi query my.browser.all --recent 4w -s | jq .url | grep 'github.com' -c
  16357
  ```



  To save databases:

  ```python
  from browserexport.save import backup_history
  backup_history("firefox", "~/data/backups")

  from browserexport.browsers.all import Firefox
  backup_history(Firefox, "~/data/backups")
  ```

  To merge/read visits from databases:

  ```python
  from browserexport.merge import read_and_merge
  read_and_merge(["/path/to/database", "/path/to/second/database", "..."])
  ```

  You can also use [`sqlite_backup`](https://github.com/purarue/sqlite_backup) to copy your current browser history into a sqlite connection in memory, as a `sqlite3.Connection`

  ```python
  from browserexport.browsers.all import Firefox
  from browserexport.parse import read_visits
  from sqlite_backup import sqlite_backup

  db_in_memory = sqlite_backup(Firefox.locate_database())
  visits = list(read_visits(db_in_memory))


  from browserexport.merge import merge_visits, read_and_merge
  merged = list(merge_visits([
      visits,
      read_and_merge(["/path/to/another/database.sqlite", "..."]),
  ]))
  ```

  If this doesn't support a browser and you wish to quickly extend without maintaining a fork (or contributing back to this repo), you can pass a `Browser` implementation (see [browsers/all.py](./browserexport/browsers/all.py) and [browsers/common.py](./browserexport/browsers/common.py) for more info) to `browserexport.parse.read_visits` or programmatically override/add your own browsers as part of the [`browserexport.browsers` namespace package](https://github.com/purarue/browserexport/blob/0705629e1dc87fe47d6f731018d26dc3720cf2fe/browserexport/browsers/all.py#L15-L24)



  A lot of the initial queries/ideas here were taken from [promnesia](https://github.com/karlicoss/promnesia) and the [`browser_history.py`](https://github.com/karlicoss/promnesia/blob/0e1e9a1ccd1f07b2a64336c18c7f41ca24fcbcd4/scripts/browser_history.py) script, but creating a package here allows its to be more extendible, e.g. allowing you to override/locate additional databases.

  TLDR on promnesia: lets you explore your browsing history in context: where you encountered it, in chat, on Twitter, on Reddit, or just in one of the text files on your computer. This is unlike most modern browsers, where you can only see when you visited the link.

  `browserexport` is now used in [promnesia](https://github.com/karlicoss/promnesia) in the [`browser` source](https://github.com/karlicoss/promnesia/blob/master/src/promnesia/sources/browser.py), see [setup](https://github.com/karlicoss/promnesia#setup) and [the browser source quickstart](https://github.com/karlicoss/promnesia/blob/master/doc/SOURCES.org#browser) in the instructions for more



  Clone the repository and [optionally] create a [virtual environment](https://docs.python.org/3/library/venv.html) to do your work in.

  ```bash
  git clone https://github.com/purarue/browserexport
  cd ./browserexport

  python -m virtualenv .venv  # python3 -m pip install virtualenv if missing
  source .venv/bin/activate
  ```



  To install, run:

  ```bash
  python3 -m pip install '.[testing]'
  ```

  If running in a virtual environment, `pip` will automatically install dependencies into your virtual environment. If running `browserexport` happens to use the globally installed `browserexport` instead, you can use `python3 -m browserexport` to ensure its using the version in your virtual environment.

  After making changes to the code, reinstall by running `pip install .`, and then test with `browserexport` or `python3 -m browserexport`



  While developing, you can run tests with:

  ```bash
  pytest
  flake8 ./browserexport
  mypy ./browserexport

  python3 -m pip install black
  find browserexport tests -name '*.py' -exec python3 -m black {} +
  ```


pkgId: 1e5594785877e055a1b84e4e1fdfc9ba32a679a4edecc45193f01b6d2b2aab24
name: python-browserforge
arch: src
version: 1.1.2
epoch: 0
release: 1
summary: Intelligent browser header & fingerprint generator
url: https://github.com/daijro/browserforge
rpm_license: Apache-2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browserforge-1.1.2-1.src.rpm
checksum_type: sha256
description:
  BrowserForge is a browser header and fingerprint generator that mimics the frequency of different browsers, operating systems, and devices found in the wild.
  It is a reimplementation of [Apify's fingerprint-suite](https://github.com/apify/fingerprint-suite) in Python.

  - Uses a Bayesian generative network to mimic actual web traffic
  - Extremely fast runtime (0.1-0.2 miliseconds)
  - Easy and simple for humans to use
  - Extensive customization options for browsers, operating systems, devices, locales, and HTTP version
  - Written with type safety

  ```
  pip install browserforge
  python -m browserforge update
  ```
  **Note:** The `browserforge update` command is needed to download model definitions. If the command is not run, files will be downloaded on the first import.
  <hr width=50>



  ```py
  >>> from browserforge.headers import HeaderGenerator
  >>> headers = HeaderGenerator()
  >>> headers.generate()
  {'sec-ch-ua': '"Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"', 'Sec-Ch-Ua-Mobile': '?0', 'Sec-Ch-Ua-Platform': '"Windows"', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 'Sec-Fetch-Site': '?1', 'Sec-Fetch-Mode': 'same-site', 'Sec-Fetch-User': 'document', 'Sec-Fetch-Dest': 'navigate', 'Accept-Encoding': 'gzip, deflate, br, zstd', 'Accept-Language': 'en-US;q=1.0'}
  ```

  Headers can be added to a session in [requests](https://github.com/psf/requests) (or similar libraries) by assigning them to the `headers` attribute:
  ```py
  import requests
  session = requests.Session()

  session.headers = headers.generate()
  ```
  <details>
  <summary>Parameters for HeaderGenerator</summary>
  ```
  Parameters:
      browser (Union[ListOrString, Iterable[Browser]], optional): Browser(s) or Browser object(s).
      os (ListOrString, optional): Operating system(s) to generate headers for.
      device (ListOrString, optional): Device(s) to generate the headers for.
      locale (ListOrString, optional): List of at most 10 languages for the Accept-Language header. Default is 'en-US'.
      http_version (Literal[1, 2], optional): Http version to be used to generate headers. Defaults to 2.
      strict (bool, optional): Throws an error if it cannot generate headers based on the input. Defaults to False.
  ```
  </details>
  <details>
  <summary>Parameters for HeaderGenerator.generate</summary>
  ```
  Generates headers using the default options and their possible overrides.
  Parameters:
      browser (Optional[Iterable[Union[str, Browser]]], optional): Browser(s) to generate the headers for.
      os (Optional[ListOrString], optional): Operating system(s) to generate the headers for.
      device (Optional[ListOrString], optional): Device(s) to generate the headers for.
      locale (Optional[ListOrString], optional): Language(s) to include in the Accept-Language header.
      http_version (Optional[Literal[1, 2]], optional): HTTP version to be used to generate headers.
      user_agent (Optional[ListOrString], optional): User-Agent(s) to use.
      request_dependent_headers (Optional[Dict[str, str]], optional): Known values of request-dependent headers.
      strict (Optional[bool], optional): If true, throws an error if it cannot generate headers based on the input.
  ```
  </details>


  Set constraints for browsers by passing the optional strings below:
  ```py
  headers = HeaderGenerator(
      browser='chrome',
      os='windows',
      device='desktop',
      locale='en-US',
      http_version=2
  )
  ```

  Set multiple constraints to select from. Options are selected based on their actual frequency in the wild:
  ```py
  headers = HeaderGenerator(
      browser=('chrome', 'firefox', 'safari', 'edge'),
      os=('windows', 'macos', 'linux', 'android', 'ios'),
      device=('desktop', 'mobile'),
      locale=('en-US', 'en', 'de'),
      http_version=2
  )
  ```

  Set specificiations for browsers, including version ranges and HTTP version:
  ```py
  from browserforge.headers import Browser
  browsers = [
      Browser(name='chrome', min_version=100, max_version=110),
      Browser(name='firefox', max_version=80, http_version=1),
      Browser(name='edge', min_version=95),
  ]
  headers = HeaderGenerator(browser=browsers)
  ```
  Note that all constraints passed into the `HeaderGenerator` constructor can be overridden by passing them into the `generate` method.

  Headers can be generated given an existing user agent:
  ```py
  >>> headers.generate(user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36')
  ```
  Select from multiple User-Agents based on their frequency in the wild:
  ```py
  >>> headers.generate(user_agent=(
      'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36',
      'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0'
  ))
  ```
  <hr width=50>


  Initialize FingerprintGenerator:
  ```py
  from browserforge.fingerprints import FingerprintGenerator
  fingerprints = FingerprintGenerator()
  fingerprints.generate()
  ```
  <details>
  <summary>Parameters for FingerprintGenerator</summary>
  ```
  Parameters:
      screen (Screen, optional): Screen constraints for the generated fingerprint.
      strict (bool, optional): Whether to raise an exception if the constraints are too strict. Default is False.
      mock_webrtc (bool, optional): Whether to mock WebRTC when injecting the fingerprint. Default is False.
      slim (bool, optional): Disables performance-heavy evasions when injecting the fingerprint. Default is False.
      **header_kwargs: Header generation options for HeaderGenerator
  ```
  </details>
  <details>
  <summary>Parameters for FingerprintGenerator.generate</summary>
  ```
  Generates a fingerprint and a matching set of ordered headers using a combination of the default options specified in the constructor and their possible overrides provided here.
  Parameters:
      screen (Screen, optional): Screen constraints for the generated fingerprint.
      strict (bool, optional): Whether to raise an exception if the constraints are too strict.
      mock_webrtc (bool, optional): Whether to mock WebRTC when injecting the fingerprint. Default is False.
      slim (bool, optional): Disables performance-heavy evasions when injecting the fingerprint. Default is False.
      **header_kwargs: Additional header generation options for HeaderGenerator.generate
  ```
  </details>
  <details>
  <summary>Example response</summary>
  ```
  Fingerprint(screen=ScreenFingerprint(availHeight=784,
                                       availWidth=1440,
                                       availTop=25,
                                       availLeft=0,
                                       colorDepth=30,
                                       height=900,
                                       pixelDepth=30,
                                       width=1440,
                                       devicePixelRatio=2,
                                       pageXOffset=0,
                                       pageYOffset=0,
                                       innerHeight=0,
                                       outerHeight=718,
                                       outerWidth=1440,
                                       innerWidth=0,
                                       screenX=0,
                                       clientWidth=0,
                                       clientHeight=19,
                                       hasHDR=True),
              navigator=NavigatorFingerprint(userAgent='Mozilla/5.0 (Macintosh; '
                                                       'Intel Mac OS X 10_15_7) '
                                                       'AppleWebKit/537.36 '
                                                       '(KHTML, like Gecko) '
                                                       'Chrome/121.0.0.0 '
                                                       'Safari/537.36',
                                             userAgentData={'architecture': 'arm',
                                                            'bitness': '64',
                                                            'brands': [{'brand': 'Not '
                                                                                 'A(Brand',
                                                                        'version': '99'},
                                                                       {'brand': 'Google '
                                                                                 'Chrome',
                                                                        'version': '121'},
                                                                       {'brand': 'Chromium',
                                                                        'version': '121'}],
                                                            'fullVersionList': [{'brand': 'Not '
                                                                                          'A(Brand',
                                                                                 'version': '99.0.0.0'},
                                                                                {'brand': 'Google '
                                                                                          'Chrome',
                                                                                 'version': '121.0.6167.160'},
                                                                                {'brand': 'Chromium',
                                                                                 'version': '121.0.6167.160'}],
                                                            'mobile': False,
                                                            'model': '',
                                                            'platform': 'macOS',
                                                            'platformVersion': '13.6.1',
                                                            'uaFullVersion': '121.0.6167.160'},
                                             doNotTrack=None,
                                             appCodeName='Mozilla',
                                             appName='Netscape',
                                             appVersion='5.0 (Macintosh; Intel '
                                                        'Mac OS X 10_15_7) '
                                                        'AppleWebKit/537.36 '
                                                        '(KHTML, like Gecko) '
                                                        'Chrome/121.0.0.0 '
                                                        'Safari/537.36',
                                             oscpu=None,
                                             webdriver=False,
                                             language='en-US',
                                             languages=['en-US'],
                                             platform='MacIntel',
                                             deviceMemory=8,
                                             hardwareConcurrency=10,
                                             product='Gecko',
                                             productSub='20030107',
                                             vendor='Google Inc.',
                                             vendorSub=None,
                                             maxTouchPoints=0,
                                             extraProperties={'globalPrivacyControl': None,
                                                              'installedApps': [],
                                                              'isBluetoothSupported': False,
                                                              'pdfViewerEnabled': True,
                                                              'vendorFlavors': ['chrome']}),
              headers={'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
                       'Accept-Encoding': 'gzip, deflate, br',
                       'Accept-Language': 'en-US;q=1.0',
                       'Sec-Fetch-Dest': 'navigate',
                       'Sec-Fetch-Mode': 'same-site',
                       'Sec-Fetch-Site': '?1',
                       'Sec-Fetch-User': 'document',
                       'Upgrade-Insecure-Requests': '1',
                       'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X '
                                     '10_15_7) AppleWebKit/537.36 (KHTML, like '
                                     'Gecko) Chrome/121.0.0.0 Safari/537.36',
                       'sec-ch-ua': '"Not A(Brand";v="99", "Google '
                                    'Chrome";v="121", "Chromium";v="121"',
                       'sec-ch-ua-mobile': '?0',
                       'sec-ch-ua-platform': '"macOS"'},
              videoCodecs={'h264': 'probably', 'ogg': '', 'webm': 'probably'},
              audioCodecs={'aac': 'probably',
                           'm4a': 'maybe',
                           'mp3': 'probably',
                           'ogg': 'probably',
                           'wav': 'probably'},
              pluginsData={'mimeTypes': ['Portable Document '
                                         'Format~~application/pdf~~pdf',
                                         'Portable Document '
                                         'Format~~text/pdf~~pdf'],
                           'plugins': [{'description': 'Portable Document Format',
                                        'filename': 'internal-pdf-viewer',
                                        'mimeTypes': [{'description': 'Portable '
                                                                      'Document '
                                                                      'Format',
                                                       'enabledPlugin': 'PDF '
                                                                        'Viewer',
                                                       'suffixes': 'pdf',
                                                       'type': 'application/pdf'},
                                                      {'description': 'Portable '
                                                                      'Document '
                                                                      'Format',
                                                       'enabledPlugin': 'PDF '
                                                                        'Viewer',
                                                       'suffixes': 'pdf',
                                                       'type': 'text/pdf'}],
                                        'name': 'PDF Viewer'},
                                       {'description': 'Portable Document Format',
                                        'filename': 'internal-pdf-viewer',
                                        'mimeTypes': [{'description': 'Portable '
                                                                      'Document '
                                                                      'Format',
                                                       'enabledPlugin': 'Chrome '
                                                                        'PDF '
                                                                        'Viewer',
                                                       'suffixes': 'pdf',
                                                       'type': 'application/pdf'},
                                                      {'description': 'Portable '
                                                                      'Document '
                                                                      'Format',
                                                       'enabledPlugin': 'Chrome '
                                                                        'PDF '
                                                                        'Viewer',
                                                       'suffixes': 'pdf',
                                                       'type': 'text/pdf'}],
                                        'name': 'Chrome PDF Viewer'},
                                       {'description': 'Portable Document Format',
                                        'filename': 'internal-pdf-viewer',
                                        'mimeTypes': [{'description': 'Portable '
                                                                      'Document '
                                                                      'Format',
                                                       'enabledPlugin': 'Chromium '
                                                                        'PDF '
                                                                        'Viewer',
                                                       'suffixes': 'pdf',
                                                       'type': 'application/pdf'},
                                                      {'description': 'Portable '
                                                                      'Document '
                                                                      'Format',
                                                       'enabledPlugin': 'Chromium '
                                                                        'PDF '
                                                                        'Viewer',
                                                       'suffixes': 'pdf',
                                                       'type': 'text/pdf'}],
                                        'name': 'Chromium PDF Viewer'},
                                       {'description': 'Portable Document Format',
                                        'filename': 'internal-pdf-viewer',
                                        'mimeTypes': [{'description': 'Portable '
                                                                      'Document '
                                                                      'Format',
                                                       'enabledPlugin': 'Microsoft '
                                                                        'Edge '
                                                                        'PDF '
                                                                        'Viewer',
                                                       'suffixes': 'pdf',
                                                       'type': 'application/pdf'},
                                                                      'Document '
                                                                      'Format',
                                                       'enabledPlugin': 'Microsoft '
                                                                        'Edge '
                                                                        'PDF '
                                                                        'Viewer',
                                                       'suffixes': 'pdf',
                                                       'type': 'text/pdf'}],
                                        'name': 'Microsoft Edge PDF Viewer'},
                                       {'description': 'Portable Document Format',
                                        'filename': 'internal-pdf-viewer',
                                        'mimeTypes': [{'description': 'Portable '
                                                                      'Document '
                                                                      'Format',
                                                       'enabledPlugin': 'WebKit '
                                                                        'built-in '
                                                                        'PDF',
                                                       'suffixes': 'pdf',
                                                       'type': 'application/pdf'},
                                                      {'description': 'Portable '
                                                                      'Document '
                                                                      'Format',
                                                       'enabledPlugin': 'WebKit '
                                                                        'built-in '
                                                                        'PDF',
                                                       'suffixes': 'pdf',
                                                       'type': 'text/pdf'}],
                                        'name': 'WebKit built-in PDF'}]},
              battery={'charging': False,
                       'chargingTime': None,
                       'dischargingTime': 29940,
                       'level': 0.98},
              videoCard=VideoCard(renderer='ANGLE (Apple, ANGLE Metal Renderer: '
                                           'Apple M2 Pro, Unspecified Version)',
                                  vendor='Google Inc. (Apple)'),
              multimediaDevices={'micros': [{'deviceId': '',
                                             'groupId': '',
                                             'kind': 'audioinput',
                                             'label': ''}],
                                 'speakers': [{'deviceId': '',
                                               'groupId': '',
                                               'kind': 'audiooutput',
                                               'label': ''}],
                                 'webcams': [{'deviceId': '',
                                              'groupId': '',
                                              'kind': 'videoinput',
                                              'label': ''}]},
              fonts=['Arial Unicode MS', 'Gill Sans', 'Helvetica Neue', 'Menlo']
              mockWebRTC: False,
              slim: False)
  ```
  </details>


  Constrain the minimum/maximum screen width and height:
  ```py
  from browserforge.fingerprints import Screen
  screen = Screen(
      min_width=100
      max_width=1280
      min_height=400
      max_height=720
  )
  fingerprints = FingerprintGenerator(screen=screen)
  ```
  Note: Not all bounds need to be defined.

  `FingerprintGenerator` and `FingerprintGenerator.generate` inherit the same parameters from `HeaderGenerator`.
  Because of this, user agents, browser specifications, device types, and operating system constrains can also be passed into `FingerprintGenerator.generate`.
  Here is a usage example:
  ```py
  fingerprint.generate(browser='chrome', os='windows')
  ```
  <hr width=50>

  BrowserForge is fully compatible with your existing Playwright and Pyppeteer code. You only have to change your context/page initialization.


  ```py

  from browserforge.injectors.playwright import AsyncNewContext
  async def main():
      async with async_playwright() as playwright:
          browser = await playwright.chromium.launch()
          
          context = await AsyncNewContext(browser, fingerprint=fingerprint)
          page = await context.new_page()
  ```
  Replace `await browser.new_context` with `await AsyncNewContext` in your existing Playwright code.
  <details>
  <summary>Parameters for AsyncNewContext</summary>
  ```
  Injects an async_api Playwright context with a Fingerprint.
  Parameters:
      browser (Browser): The browser to create the context in
      fingerprint (Optional[Fingerprint]): The fingerprint to inject. If None, one will be generated
      fingerprint_options (Optional[Dict]): Options for the Fingerprint generator if `fingerprint` is not passed
      **new_context_options: Other options for the new context
  ```
  </details>

  ```py

  from browserforge.injectors.playwright import NewContext
  def main():
      with sync_playwright() as playwright:
          browser = playwright.chromium.launch()
          
          context = NewContext(browser, fingerprint=fingerprint)
          page = context.new_page()
  ```
  Replace `browser.new_context` with `NewContext` in your existing Playwright code.
  <details>
  <summary>Parameters for NewContext</summary>
  ```
  Injects a sync_api Playwright context with a Fingerprint.
  Parameters:
      browser (Browser): The browser to create the context in
      fingerprint (Optional[Fingerprint]): The fingerprint to inject. If None, one will be generated
      fingerprint_options (Optional[Dict]): Options for the Fingerprint generator if `fingerprint` is not passed
      **new_context_options: Other options for the new context
  ```
  </details>

  [Undetected-Playwright](https://github.com/kaliiiiiiiiii/undetected-playwright-python) is also supported in the `browserforge.injectors.undetected_playwright` package. The usage is the same as the Playwright injector.

  ```py

  from browserforge.injectors.pyppeteer import NewPage
  from pyppeteer import launch
  async def test():
      browser = await launch()
      
      page = await NewPage(browser, fingerprint=fingerprint)
  ```
  Replace `browser.newPage` with `NewPage` in your existing Pyppeteer code.
  <details>
  <summary>Parameters for NewPage</summary>
  ```
  Injects a Pyppeteer browser object with a Fingerprint.
  Parameters:
      browser (Browser): The browser to create the context in
      fingerprint (Optional[Fingerprint]): The fingerprint to inject. If None, one will be generated
      fingerprint_options (Optional[Dict]): Options for the Fingerprint generator if `fingerprint` is not passed
  ```
  </details>
  <hr width=50>

  To fully remove all files, run the following commands:
  ```
  python -m browserforge remove
  pip uninstall browserforge


pkgId: e6b766caeb4aeff6ddd24e15b1faad8da28b1a502bdc8ba7d4ad3bb927b0bf3e
name: python-browsergui
arch: src
version: 0.4
epoch: 0
release: 1
summary: A GUI toolkit targeting browsers
url: https://github.com/speezepearson/browsergui
rpm_license: UNKNOWN
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browsergui-0.4-1.src.rpm
checksum_type: sha256
description:
  It's a GUI framework prioritizing portability, simplicity, and a Pythonic feel.
  If you want to build a simple GUI for a simple task, I recommend this package whole-heartedly. I don't think this is just pride in my own work -- I'm pretty sure that this package *actually is* very easy to learn, and very good for simple things.
  If you want to build a video game, or a nice, fluid 3D visualization, this is easily the worst GUI framework I have ever seen.
  - [Why is it good?](#why-is-it-good)
  - [Why is it bad?](#why-is-it-bad)
  - [What are the alternatives?](#what-are-the-alternatives)
  - [How do I install it?](#how-do-i-install-it)
  - [How do I learn to use it?](#how-do-i-learn-to-use-it)


pkgId: 0e0624878865a89df05ae4e3a9a302b93c5cca38b18adff5951d170f92a6b51a
name: python-browserist
arch: src
version: 1.6.19
epoch: 0
release: 1
summary: Extension for the Selenium web driver that makes browser automation even easier
url: https://jakob-bagterp.github.io/browserist/
rpm_license: Apache-2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browserist-1.6.19-1.src.rpm
checksum_type: sha256
description:
  [![Latest version](https://img.shields.io/static/v1?label=version&message=1.6.19&color=yellowgreen)](https://github.com/jakob-bagterp/browserist/releases/latest)
  [![Python 3.10 | 3.11 | 3.12 | 3.13+](https://img.shields.io/static/v1?label=python&message=3.10%20|%203.11%20|%203.12%20|%203.13%2B&color=blueviolet)](https://www.python.org)
  [![Apache 2.0 license](https://img.shields.io/static/v1?label=license&message=Apache%202.0&color=blue)](https://github.com/jakob-bagterp/browserist/blob/master/LICENSE.md)
  [![Codecov](https://codecov.io/gh/jakob-bagterp/browserist/branch/master/graph/badge.svg?token=1JL65T099J)](https://codecov.io/gh/jakob-bagterp/browserist)
  [![CodeQL](https://github.com/jakob-bagterp/browserist/actions/workflows/codeql.yml/badge.svg)](https://github.com/jakob-bagterp/browserist/actions/workflows/codeql.yml)
  [![Test](https://github.com/jakob-bagterp/browserist/actions/workflows/test.yml/badge.svg)](https://github.com/jakob-bagterp/browserist/actions/workflows/test.yml)
  [![Downloads](https://static.pepy.tech/badge/browserist)](https://pepy.tech/project/browserist)


  > **browserist**
  > 1. The belief that web browsers account for differences in websites or web applications in all of their ability and that a particular web browser is superior to others.
  > 2. Discrimination or prejudice based on web browser.

  Despite the [urban definition](https://www.urbandictionary.com/define.php?term=browserist), Browserist is a Python extension of the [Selenium web driver](https://www.selenium.dev/) that makes it even easier to use different browsers for testing and automation.


  With Browserist as an extension to Selenium, you get:

  * Improved stability and speed
  * Simple syntax and less code
  * Hassle-free setup across browsers: Chrome, Firefox, Edge, Safari, Internet Explorer
  * Extensive framework of functions that makes browser automation easy
  * Efficient development workflow with IntelliSense and type hints


  Ready to try? With [PyPI](https://pypi.org/project/browserist/):

  ```shell
  pip install browserist
  ```

  Or with [Homebrew](https://brew.sh):

  ```shell
  brew tap jakob-bagterp/browserist
  brew install browserist
  ```

  Find more installation details [here](https://jakob-bagterp.github.io/browserist/getting-started/installation/).


  You're now ready to go:

  ```python
  from browserist import Browser

  with Browser() as browser:
      browser.open.url("https://example.com")
      browser.wait.seconds(5)
  ```


  Browserist improves stability with less code compared to standard use of Selenium. As browsers need time to render web pages, especially single-page applications, Selenium is often used with explicit timeouts:

  ```python
  from selenium import webdriver
  from selenium.webdriver.common.by import By

  driver = webdriver.Chrome()

  driver.get("https://example.com")
  driver.implicitly_wait(3)
  search_box = driver.find_element(By.XPATH, "//xpath/to/input")
  search_button = driver.find_element(By.XPATH, "//xpath/to/button")
  search_box.send_keys("Lorem ipsum")
  search_button.click()
  driver.quit()
  ```

  Browserist does the same with less and cleaner code, yet also with increased stability and without explicit/implicit waits:

  ```python
  from browserist import Browser

  with Browser() as browser:
      browser.open.url("https://example.com")
      browser.input.value("//xpath/to/input", "Lorem ipsum")
      browser.click.button("//xpath/to/button")
  ```


  Find tutorials, code examples, list of all methods and much more [here](https://jakob-bagterp.github.io/browserist).



  This module is free to use. And if you like it, feel free to [sponsor the project](https://github.com/sponsors/jakob-bagterp).


  If you have suggestions or changes to the module, feel free to add to the code and create a [pull request](https://github.com/jakob-bagterp/browserist/pulls).


  Report bugs and issues [here](https://github.com/jakob-bagterp/browserist/issues).

                                   Apache License
                             Version 2.0, January 2004
                          http://www.apache.org/licenses/

     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

     1. Definitions.

        "License" shall mean the terms and conditions for use, reproduction,
        and distribution as defined by Sections 1 through 9 of this document.

        "Licensor" shall mean the copyright owner or entity authorized by
        the copyright owner that is granting the License.

        "Legal Entity" shall mean the union of the acting entity and all
        other entities that control, are controlled by, or are under common
        control with that entity. For the purposes of this definition,
        "control" means (i) the power, direct or indirect, to cause the
        direction or management of such entity, whether by contract or
        otherwise, or (ii) ownership of fifty percent (50%) or more of the
        outstanding shares, or (iii) beneficial ownership of such entity.

        "You" (or "Your") shall mean an individual or Legal Entity
        exercising permissions granted by this License.

        "Source" form shall mean the preferred form for making modifications,
        including but not limited to software source code, documentation
        source, and configuration files.

        "Object" form shall mean any form resulting from mechanical
        transformation or translation of a Source form, including but
        not limited to compiled object code, generated documentation,
        and conversions to other media types.

        "Work" shall mean the work of authorship, whether in Source or
        Object form, made available under the License, as indicated by a
        copyright notice that is included in or attached to the work
        (an example is provided in the Appendix below).

        "Derivative Works" shall mean any work, whether in Source or Object
        form, that is based on (or derived from) the Work and for which the
        editorial revisions, annotations, elaborations, or other modifications
        represent, as a whole, an original work of authorship. For the purposes
        of this License, Derivative Works shall not include works that remain
        separable from, or merely link (or bind by name) to the interfaces of,
        the Work and Derivative Works thereof.

        "Contribution" shall mean any work of authorship, including
        the original version of the Work and any modifications or additions
        to that Work or Derivative Works thereof, that is intentionally
        submitted to Licensor for inclusion in the Work by the copyright owner
        or by an individual or Legal Entity authorized to submit on behalf of
        the copyright owner. For the purposes of this definition, "submitted"
        means any form of electronic, verbal, or written communication sent
        to the Licensor or its representatives, including but not limited to
        communication on electronic mailing lists, source code control systems,
        and issue tracking systems that are managed by, or on behalf of, the
        Licensor for the purpose of discussing and improving the Work, but
        excluding communication that is conspicuously marked or otherwise
        designated in writing by the copyright owner as "Not a Contribution."

        "Contributor" shall mean Licensor and any individual or Legal Entity
        on behalf of whom a Contribution has been received by Licensor and
        subsequently incorporated within the Work.

     2. Grant of Copyright License. Subject to the terms and conditions of
        this License, each Contributor hereby grants to You a perpetual,
        worldwide, non-exclusive, no-charge, royalty-free, irrevocable
        copyright license to reproduce, prepare Derivative Works of,
        publicly display, publicly perform, sublicense, and distribute the
        Work and such Derivative Works in Source or Object form.

     3. Grant of Patent License. Subject to the terms and conditions of
        this License, each Contributor hereby grants to You a perpetual,
        worldwide, non-exclusive, no-charge, royalty-free, irrevocable
        (except as stated in this section) patent license to make, have made,
        use, offer to sell, sell, import, and otherwise transfer the Work,
        where such license applies only to those patent claims licensable
        by such Contributor that are necessarily infringed by their
        Contribution(s) alone or by combination of their Contribution(s)
        with the Work to which such Contribution(s) was submitted. If You
        institute patent litigation against any entity (including a
        cross-claim or counterclaim in a lawsuit) alleging that the Work
        or a Contribution incorporated within the Work constitutes direct
        or contributory patent infringement, then any patent licenses
        granted to You under this License for that Work shall terminate
        as of the date such litigation is filed.

     4. Redistribution. You may reproduce and distribute copies of the
        Work or Derivative Works thereof in any medium, with or without
        modifications, and in Source or Object form, provided that You
        meet the following conditions:

        (a) You must give any other recipients of the Work or
            Derivative Works a copy of this License; and

        (b) You must cause any modified files to carry prominent notices
            stating that You changed the files; and

        (c) You must retain, in the Source form of any Derivative Works
            that You distribute, all copyright, patent, trademark, and
            attribution notices from the Source form of the Work,
            excluding those notices that do not pertain to any part of
            the Derivative Works; and

        (d) If the Work includes a "NOTICE" text file as part of its
            distribution, then any Derivative Works that You distribute must
            include a readable copy of the attribution notices contained
            within such NOTICE file, excluding those notices that do not
            pertain to any part of the Derivative Works, in at least one
            of the following places: within a NOTICE text file distributed
            as part of the Derivative Works; within the Source form or
            documentation, if provided along with the Derivative Works; or,
            within a display generated by the Derivative Works, if and
            wherever such third-party notices normally appear. The contents
            of the NOTICE file are for informational purposes only and
            do not modify the License. You may add Your own attribution
            notices within Derivative Works that You distribute, alongside
            or as an addendum to the NOTICE text from the Work, provided
            that such additional attribution notices cannot be construed
            as modifying the License.

        You may add Your own copyright statement to Your modifications and
        may provide additional or different license terms and conditions
        for use, reproduction, or distribution of Your modifications, or
        for any such Derivative Works as a whole, provided Your use,
        reproduction, and distribution of the Work otherwise complies with
        the conditions stated in this License.

     5. Submission of Contributions. Unless You explicitly state otherwise,
        any Contribution intentionally submitted for inclusion in the Work
        by You to the Licensor shall be under the terms and conditions of
        this License, without any additional terms or conditions.
        Notwithstanding the above, nothing herein shall supersede or modify
        the terms of any separate license agreement you may have executed
        with Licensor regarding such Contributions.

     6. Trademarks. This License does not grant permission to use the trade
        names, trademarks, service marks, or product names of the Licensor,
        except as required for reasonable and customary use in describing the
        origin of the Work and reproducing the content of the NOTICE file.

     7. Disclaimer of Warranty. Unless required by applicable law or
        agreed to in writing, Licensor provides the Work (and each
        Contributor provides its Contributions) on an "AS IS" BASIS,
        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
        implied, including, without limitation, any warranties or conditions
        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
        PARTICULAR PURPOSE. You are solely responsible for determining the
        appropriateness of using or redistributing the Work and assume any
        risks associated with Your exercise of permissions under this License.

     8. Limitation of Liability. In no event and under no legal theory,
        whether in tort (including negligence), contract, or otherwise,
        unless required by applicable law (such as deliberate and grossly
        negligent acts) or agreed to in writing, shall any Contributor be
        liable to You for damages, including any direct, indirect, special,
        incidental, or consequential damages of any character arising as a
        result of this License or out of the use or inability to use the
        Work (including but not limited to damages for loss of goodwill,
        work stoppage, computer failure or malfunction, or any and all
        other commercial damages or losses), even if such Contributor
        has been advised of the possibility of such damages.

     9. Accepting Warranty or Additional Liability. While redistributing
        the Work or Derivative Works thereof, You may choose to offer,
        and charge a fee for, acceptance of support, warranty, indemnity,
        or other liability obligations and/or rights consistent with this
        License. However, in accepting such obligations, You may act only
        on Your own behalf and on Your sole responsibility, not on behalf
        of any other Contributor, and only if You agree to indemnify,
        defend, and hold each Contributor harmless for any liability
        incurred by, or claims asserted against, such Contributor by reason
        of your accepting any such warranty or additional liability.

     END OF TERMS AND CONDITIONS

     APPENDIX: How to apply the Apache License to your work.

        To apply the Apache License to your work, attach the following
        boilerplate notice, with the fields enclosed by brackets "[]"
        replaced with your own identifying information. (Don't include
        the brackets!)  The text should be enclosed in the appropriate
        comment syntax for the file format. We also recommend that a
        file or class name and description of purpose be included on the
        same "printed page" as the copyright notice for easier
        identification within third-party archives.

     Copyright 2022 Jakob Bagterp

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.


pkgId: e16fc1e70711d0cd4604dda7a1283d75fe53a8a0391739fd15539453990c8126
name: python-browserist
arch: src
version: 1.6.22
epoch: 0
release: 1
summary: Extension for the Selenium web driver that makes browser automation even easier
url: https://jakob-bagterp.github.io/browserist/
rpm_license: Apache-2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browserist-1.6.22-1.src.rpm
checksum_type: sha256
description:
  [![Latest version](https://img.shields.io/static/v1?label=version&message=1.6.22&color=yellowgreen)](https://github.com/jakob-bagterp/browserist/releases/latest)
  [![Python 3.10 | 3.11 | 3.12 | 3.13+](https://img.shields.io/static/v1?label=python&message=3.10%20|%203.11%20|%203.12%20|%203.13%2B&color=blueviolet)](https://www.python.org)
  [![Apache 2.0 license](https://img.shields.io/static/v1?label=license&message=Apache%202.0&color=blue)](https://github.com/jakob-bagterp/browserist/blob/master/LICENSE.md)
  [![Codecov](https://codecov.io/gh/jakob-bagterp/browserist/branch/master/graph/badge.svg?token=1JL65T099J)](https://codecov.io/gh/jakob-bagterp/browserist)
  [![CodeQL](https://github.com/jakob-bagterp/browserist/actions/workflows/codeql.yml/badge.svg)](https://github.com/jakob-bagterp/browserist/actions/workflows/codeql.yml)
  [![Test](https://github.com/jakob-bagterp/browserist/actions/workflows/test.yml/badge.svg)](https://github.com/jakob-bagterp/browserist/actions/workflows/test.yml)
  [![Downloads](https://static.pepy.tech/badge/browserist)](https://pepy.tech/project/browserist)


  > **browserist**
  > 1. The belief that web browsers account for differences in websites or web applications in all of their ability and that a particular web browser is superior to others.
  > 2. Discrimination or prejudice based on web browser.

  Despite the [urban definition](https://www.urbandictionary.com/define.php?term=browserist), Browserist is a Python extension of the [Selenium web driver](https://www.selenium.dev/) that makes it even easier to use different browsers for testing and automation.


  With Browserist as an extension to Selenium, you get:

  * Improved stability and speed
  * Simple syntax and less code
  * Hassle-free setup across browsers: Chrome, Firefox, Edge, Safari, Internet Explorer
  * Extensive framework of functions that makes browser automation easy
  * Efficient development workflow with IntelliSense and type hints


  Ready to try? With [PyPI](https://pypi.org/project/browserist/):

  ```shell
  pip install browserist
  ```

  Or with [Homebrew](https://brew.sh):

  ```shell
  brew tap jakob-bagterp/browserist
  brew install browserist
  ```

  Find more installation details [here](https://jakob-bagterp.github.io/browserist/getting-started/installation/).


  You're now ready to go:

  ```python
  from browserist import Browser

  with Browser() as browser:
      browser.open.url("https://example.com")
      browser.wait.seconds(5)
  ```


  Browserist improves stability with less code compared to standard use of Selenium. As browsers need time to render web pages, especially single-page applications, Selenium is often used with explicit timeouts:

  ```python
  from selenium import webdriver
  from selenium.webdriver.common.by import By

  driver = webdriver.Chrome()

  driver.get("https://example.com")
  driver.implicitly_wait(3)
  search_box = driver.find_element(By.XPATH, "//xpath/to/input")
  search_button = driver.find_element(By.XPATH, "//xpath/to/button")
  search_box.send_keys("Lorem ipsum")
  search_button.click()
  driver.quit()
  ```

  Browserist does the same with less and cleaner code, yet also with increased stability and without explicit/implicit waits:

  ```python
  from browserist import Browser

  with Browser() as browser:
      browser.open.url("https://example.com")
      browser.input.value("//xpath/to/input", "Lorem ipsum")
      browser.click.button("//xpath/to/button")
  ```


  Find tutorials, code examples, list of all methods and much more [here](https://jakob-bagterp.github.io/browserist).



  This module is free to use. And if you like it, feel free to [sponsor the project](https://github.com/sponsors/jakob-bagterp).


  If you have suggestions or changes to the module, feel free to add to the code and create a [pull request](https://github.com/jakob-bagterp/browserist/pulls).


  Report bugs and issues [here](https://github.com/jakob-bagterp/browserist/issues).

                                   Apache License
                             Version 2.0, January 2004
                          http://www.apache.org/licenses/

     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

     1. Definitions.

        "License" shall mean the terms and conditions for use, reproduction,
        and distribution as defined by Sections 1 through 9 of this document.

        "Licensor" shall mean the copyright owner or entity authorized by
        the copyright owner that is granting the License.

        "Legal Entity" shall mean the union of the acting entity and all
        other entities that control, are controlled by, or are under common
        control with that entity. For the purposes of this definition,
        "control" means (i) the power, direct or indirect, to cause the
        direction or management of such entity, whether by contract or
        otherwise, or (ii) ownership of fifty percent (50%) or more of the
        outstanding shares, or (iii) beneficial ownership of such entity.

        "You" (or "Your") shall mean an individual or Legal Entity
        exercising permissions granted by this License.

        "Source" form shall mean the preferred form for making modifications,
        including but not limited to software source code, documentation
        source, and configuration files.

        "Object" form shall mean any form resulting from mechanical
        transformation or translation of a Source form, including but
        not limited to compiled object code, generated documentation,
        and conversions to other media types.

        "Work" shall mean the work of authorship, whether in Source or
        Object form, made available under the License, as indicated by a
        copyright notice that is included in or attached to the work
        (an example is provided in the Appendix below).

        "Derivative Works" shall mean any work, whether in Source or Object
        form, that is based on (or derived from) the Work and for which the
        editorial revisions, annotations, elaborations, or other modifications
        represent, as a whole, an original work of authorship. For the purposes
        of this License, Derivative Works shall not include works that remain
        separable from, or merely link (or bind by name) to the interfaces of,
        the Work and Derivative Works thereof.

        "Contribution" shall mean any work of authorship, including
        the original version of the Work and any modifications or additions
        to that Work or Derivative Works thereof, that is intentionally
        submitted to Licensor for inclusion in the Work by the copyright owner
        or by an individual or Legal Entity authorized to submit on behalf of
        the copyright owner. For the purposes of this definition, "submitted"
        means any form of electronic, verbal, or written communication sent
        to the Licensor or its representatives, including but not limited to
        communication on electronic mailing lists, source code control systems,
        and issue tracking systems that are managed by, or on behalf of, the
        Licensor for the purpose of discussing and improving the Work, but
        excluding communication that is conspicuously marked or otherwise
        designated in writing by the copyright owner as "Not a Contribution."

        "Contributor" shall mean Licensor and any individual or Legal Entity
        on behalf of whom a Contribution has been received by Licensor and
        subsequently incorporated within the Work.

     2. Grant of Copyright License. Subject to the terms and conditions of
        this License, each Contributor hereby grants to You a perpetual,
        worldwide, non-exclusive, no-charge, royalty-free, irrevocable
        copyright license to reproduce, prepare Derivative Works of,
        publicly display, publicly perform, sublicense, and distribute the
        Work and such Derivative Works in Source or Object form.

     3. Grant of Patent License. Subject to the terms and conditions of
        this License, each Contributor hereby grants to You a perpetual,
        worldwide, non-exclusive, no-charge, royalty-free, irrevocable
        (except as stated in this section) patent license to make, have made,
        use, offer to sell, sell, import, and otherwise transfer the Work,
        where such license applies only to those patent claims licensable
        by such Contributor that are necessarily infringed by their
        Contribution(s) alone or by combination of their Contribution(s)
        with the Work to which such Contribution(s) was submitted. If You
        institute patent litigation against any entity (including a
        cross-claim or counterclaim in a lawsuit) alleging that the Work
        or a Contribution incorporated within the Work constitutes direct
        or contributory patent infringement, then any patent licenses
        granted to You under this License for that Work shall terminate
        as of the date such litigation is filed.

     4. Redistribution. You may reproduce and distribute copies of the
        Work or Derivative Works thereof in any medium, with or without
        modifications, and in Source or Object form, provided that You
        meet the following conditions:

        (a) You must give any other recipients of the Work or
            Derivative Works a copy of this License; and

        (b) You must cause any modified files to carry prominent notices
            stating that You changed the files; and

        (c) You must retain, in the Source form of any Derivative Works
            that You distribute, all copyright, patent, trademark, and
            attribution notices from the Source form of the Work,
            excluding those notices that do not pertain to any part of
            the Derivative Works; and

        (d) If the Work includes a "NOTICE" text file as part of its
            distribution, then any Derivative Works that You distribute must
            include a readable copy of the attribution notices contained
            within such NOTICE file, excluding those notices that do not
            pertain to any part of the Derivative Works, in at least one
            of the following places: within a NOTICE text file distributed
            as part of the Derivative Works; within the Source form or
            documentation, if provided along with the Derivative Works; or,
            within a display generated by the Derivative Works, if and
            wherever such third-party notices normally appear. The contents
            of the NOTICE file are for informational purposes only and
            do not modify the License. You may add Your own attribution
            notices within Derivative Works that You distribute, alongside
            or as an addendum to the NOTICE text from the Work, provided
            that such additional attribution notices cannot be construed
            as modifying the License.

        You may add Your own copyright statement to Your modifications and
        may provide additional or different license terms and conditions
        for use, reproduction, or distribution of Your modifications, or
        for any such Derivative Works as a whole, provided Your use,
        reproduction, and distribution of the Work otherwise complies with
        the conditions stated in this License.

     5. Submission of Contributions. Unless You explicitly state otherwise,
        any Contribution intentionally submitted for inclusion in the Work
        by You to the Licensor shall be under the terms and conditions of
        this License, without any additional terms or conditions.
        Notwithstanding the above, nothing herein shall supersede or modify
        the terms of any separate license agreement you may have executed
        with Licensor regarding such Contributions.

     6. Trademarks. This License does not grant permission to use the trade
        names, trademarks, service marks, or product names of the Licensor,
        except as required for reasonable and customary use in describing the
        origin of the Work and reproducing the content of the NOTICE file.

     7. Disclaimer of Warranty. Unless required by applicable law or
        agreed to in writing, Licensor provides the Work (and each
        Contributor provides its Contributions) on an "AS IS" BASIS,
        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
        implied, including, without limitation, any warranties or conditions
        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
        PARTICULAR PURPOSE. You are solely responsible for determining the
        appropriateness of using or redistributing the Work and assume any
        risks associated with Your exercise of permissions under this License.

     8. Limitation of Liability. In no event and under no legal theory,
        whether in tort (including negligence), contract, or otherwise,
        unless required by applicable law (such as deliberate and grossly
        negligent acts) or agreed to in writing, shall any Contributor be
        liable to You for damages, including any direct, indirect, special,
        incidental, or consequential damages of any character arising as a
        result of this License or out of the use or inability to use the
        Work (including but not limited to damages for loss of goodwill,
        work stoppage, computer failure or malfunction, or any and all
        other commercial damages or losses), even if such Contributor
        has been advised of the possibility of such damages.

     9. Accepting Warranty or Additional Liability. While redistributing
        the Work or Derivative Works thereof, You may choose to offer,
        and charge a fee for, acceptance of support, warranty, indemnity,
        or other liability obligations and/or rights consistent with this
        License. However, in accepting such obligations, You may act only
        on Your own behalf and on Your sole responsibility, not on behalf
        of any other Contributor, and only if You agree to indemnify,
        defend, and hold each Contributor harmless for any liability
        incurred by, or claims asserted against, such Contributor by reason
        of your accepting any such warranty or additional liability.

     END OF TERMS AND CONDITIONS

     APPENDIX: How to apply the Apache License to your work.

        To apply the Apache License to your work, attach the following
        boilerplate notice, with the fields enclosed by brackets "[]"
        replaced with your own identifying information. (Don't include
        the brackets!)  The text should be enclosed in the appropriate
        comment syntax for the file format. We also recommend that a
        file or class name and description of purpose be included on the
        same "printed page" as the copyright notice for easier
        identification within third-party archives.

     Copyright 2022 Jakob Bagterp

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.


pkgId: 1acacba5fc3632e806cd89cb9f6b13a4a17870956e17ea1161dd9641f65df984
name: python-browserist
arch: src
version: 1.6.23
epoch: 0
release: 1
summary: Extension for the Selenium web driver that makes browser automation even easier
url: https://jakob-bagterp.github.io/browserist/
rpm_license: Apache-2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browserist-1.6.23-1.src.rpm
checksum_type: sha256
description:
  [![Latest version](https://img.shields.io/static/v1?label=version&message=1.6.23&color=yellowgreen)](https://github.com/jakob-bagterp/browserist/releases/latest)
  [![Python 3.10 | 3.11 | 3.12 | 3.13+](https://img.shields.io/static/v1?label=python&message=3.10%20|%203.11%20|%203.12%20|%203.13%2B&color=blueviolet)](https://www.python.org)
  [![Apache 2.0 license](https://img.shields.io/static/v1?label=license&message=Apache%202.0&color=blue)](https://github.com/jakob-bagterp/browserist/blob/master/LICENSE.md)
  [![Codecov](https://codecov.io/gh/jakob-bagterp/browserist/branch/master/graph/badge.svg?token=1JL65T099J)](https://codecov.io/gh/jakob-bagterp/browserist)
  [![CodeQL](https://github.com/jakob-bagterp/browserist/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/jakob-bagterp/browserist/actions/workflows/github-code-scanning/codeql)
  [![Test](https://github.com/jakob-bagterp/browserist/actions/workflows/test.yml/badge.svg)](https://github.com/jakob-bagterp/browserist/actions/workflows/test.yml)
  [![Downloads](https://static.pepy.tech/badge/browserist)](https://pepy.tech/project/browserist)


  > **browserist**
  > 1. The belief that web browsers account for differences in websites or web applications in all of their ability and that a particular web browser is superior to others.
  > 2. Discrimination or prejudice based on web browser.

  Despite the [urban definition](https://www.urbandictionary.com/define.php?term=browserist), Browserist is a Python extension of the [Selenium web driver](https://www.selenium.dev/) that makes it even easier to use different browsers for testing and automation.


  With Browserist as an extension to Selenium, you get:

  * Improved stability and speed
  * Simple syntax and less code
  * Hassle-free setup across browsers: Chrome, Firefox, Edge, Safari, Internet Explorer
  * Extensive framework of functions that makes browser automation easy
  * Efficient development workflow with IntelliSense and type hints


  Ready to try? With [PyPI](https://pypi.org/project/browserist/):

  ```shell
  pip install browserist
  ```

  Or with [Homebrew](https://brew.sh):

  ```shell
  brew tap jakob-bagterp/browserist
  brew install browserist
  ```

  Find more installation details [here](https://jakob-bagterp.github.io/browserist/getting-started/installation/).


  You're now ready to go:

  ```python
  from browserist import Browser

  with Browser() as browser:
      browser.open.url("https://example.com")
      browser.wait.seconds(5)
  ```


  Browserist improves stability with less code compared to standard use of Selenium. As browsers need time to render web pages, especially single-page applications, Selenium is often used with explicit timeouts:

  ```python
  from selenium import webdriver
  from selenium.webdriver.common.by import By

  driver = webdriver.Chrome()

  driver.get("https://example.com")
  driver.implicitly_wait(3)
  search_box = driver.find_element(By.XPATH, "//xpath/to/input")
  search_button = driver.find_element(By.XPATH, "//xpath/to/button")
  search_box.send_keys("Lorem ipsum")
  search_button.click()
  driver.quit()
  ```

  Browserist does the same with less and cleaner code, yet also with increased stability and without explicit/implicit waits:

  ```python
  from browserist import Browser

  with Browser() as browser:
      browser.open.url("https://example.com")
      browser.input.value("//xpath/to/input", "Lorem ipsum")
      browser.click.button("//xpath/to/button")
  ```


  Find tutorials, code examples, list of all methods and much more [here](https://jakob-bagterp.github.io/browserist).


  If you find this project helpful, please consider supporting its development. Your donations will help keep it alive and growing. Every contribution, no matter the size, makes a difference.

  [Donate on GitHub Sponsors](https://github.com/sponsors/jakob-bagterp)

  Thank you for your support! 🙌


  If you have suggestions or changes to the module, feel free to add to the code and create a [pull request](https://github.com/jakob-bagterp/browserist/pulls).


  Report bugs and issues [here](https://github.com/jakob-bagterp/browserist/issues).

                                   Apache License
                             Version 2.0, January 2004
                          http://www.apache.org/licenses/

     TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

     1. Definitions.

        "License" shall mean the terms and conditions for use, reproduction,
        and distribution as defined by Sections 1 through 9 of this document.

        "Licensor" shall mean the copyright owner or entity authorized by
        the copyright owner that is granting the License.

        "Legal Entity" shall mean the union of the acting entity and all
        other entities that control, are controlled by, or are under common
        control with that entity. For the purposes of this definition,
        "control" means (i) the power, direct or indirect, to cause the
        direction or management of such entity, whether by contract or
        otherwise, or (ii) ownership of fifty percent (50%) or more of the
        outstanding shares, or (iii) beneficial ownership of such entity.

        "You" (or "Your") shall mean an individual or Legal Entity
        exercising permissions granted by this License.

        "Source" form shall mean the preferred form for making modifications,
        including but not limited to software source code, documentation
        source, and configuration files.

        "Object" form shall mean any form resulting from mechanical
        transformation or translation of a Source form, including but
        not limited to compiled object code, generated documentation,
        and conversions to other media types.

        "Work" shall mean the work of authorship, whether in Source or
        Object form, made available under the License, as indicated by a
        copyright notice that is included in or attached to the work
        (an example is provided in the Appendix below).

        "Derivative Works" shall mean any work, whether in Source or Object
        form, that is based on (or derived from) the Work and for which the
        editorial revisions, annotations, elaborations, or other modifications
        represent, as a whole, an original work of authorship. For the purposes
        of this License, Derivative Works shall not include works that remain
        separable from, or merely link (or bind by name) to the interfaces of,
        the Work and Derivative Works thereof.

        "Contribution" shall mean any work of authorship, including
        the original version of the Work and any modifications or additions
        to that Work or Derivative Works thereof, that is intentionally
        submitted to Licensor for inclusion in the Work by the copyright owner
        or by an individual or Legal Entity authorized to submit on behalf of
        the copyright owner. For the purposes of this definition, "submitted"
        means any form of electronic, verbal, or written communication sent
        to the Licensor or its representatives, including but not limited to
        communication on electronic mailing lists, source code control systems,
        and issue tracking systems that are managed by, or on behalf of, the
        Licensor for the purpose of discussing and improving the Work, but
        excluding communication that is conspicuously marked or otherwise
        designated in writing by the copyright owner as "Not a Contribution."

        "Contributor" shall mean Licensor and any individual or Legal Entity
        on behalf of whom a Contribution has been received by Licensor and
        subsequently incorporated within the Work.

     2. Grant of Copyright License. Subject to the terms and conditions of
        this License, each Contributor hereby grants to You a perpetual,
        worldwide, non-exclusive, no-charge, royalty-free, irrevocable
        copyright license to reproduce, prepare Derivative Works of,
        publicly display, publicly perform, sublicense, and distribute the
        Work and such Derivative Works in Source or Object form.

     3. Grant of Patent License. Subject to the terms and conditions of
        this License, each Contributor hereby grants to You a perpetual,
        worldwide, non-exclusive, no-charge, royalty-free, irrevocable
        (except as stated in this section) patent license to make, have made,
        use, offer to sell, sell, import, and otherwise transfer the Work,
        where such license applies only to those patent claims licensable
        by such Contributor that are necessarily infringed by their
        Contribution(s) alone or by combination of their Contribution(s)
        with the Work to which such Contribution(s) was submitted. If You
        institute patent litigation against any entity (including a
        cross-claim or counterclaim in a lawsuit) alleging that the Work
        or a Contribution incorporated within the Work constitutes direct
        or contributory patent infringement, then any patent licenses
        granted to You under this License for that Work shall terminate
        as of the date such litigation is filed.

     4. Redistribution. You may reproduce and distribute copies of the
        Work or Derivative Works thereof in any medium, with or without
        modifications, and in Source or Object form, provided that You
        meet the following conditions:

        (a) You must give any other recipients of the Work or
            Derivative Works a copy of this License; and

        (b) You must cause any modified files to carry prominent notices
            stating that You changed the files; and

        (c) You must retain, in the Source form of any Derivative Works
            that You distribute, all copyright, patent, trademark, and
            attribution notices from the Source form of the Work,
            excluding those notices that do not pertain to any part of
            the Derivative Works; and

        (d) If the Work includes a "NOTICE" text file as part of its
            distribution, then any Derivative Works that You distribute must
            include a readable copy of the attribution notices contained
            within such NOTICE file, excluding those notices that do not
            pertain to any part of the Derivative Works, in at least one
            of the following places: within a NOTICE text file distributed
            as part of the Derivative Works; within the Source form or
            documentation, if provided along with the Derivative Works; or,
            within a display generated by the Derivative Works, if and
            wherever such third-party notices normally appear. The contents
            of the NOTICE file are for informational purposes only and
            do not modify the License. You may add Your own attribution
            notices within Derivative Works that You distribute, alongside
            or as an addendum to the NOTICE text from the Work, provided
            that such additional attribution notices cannot be construed
            as modifying the License.

        You may add Your own copyright statement to Your modifications and
        may provide additional or different license terms and conditions
        for use, reproduction, or distribution of Your modifications, or
        for any such Derivative Works as a whole, provided Your use,
        reproduction, and distribution of the Work otherwise complies with
        the conditions stated in this License.

     5. Submission of Contributions. Unless You explicitly state otherwise,
        any Contribution intentionally submitted for inclusion in the Work
        by You to the Licensor shall be under the terms and conditions of
        this License, without any additional terms or conditions.
        Notwithstanding the above, nothing herein shall supersede or modify
        the terms of any separate license agreement you may have executed
        with Licensor regarding such Contributions.

     6. Trademarks. This License does not grant permission to use the trade
        names, trademarks, service marks, or product names of the Licensor,
        except as required for reasonable and customary use in describing the
        origin of the Work and reproducing the content of the NOTICE file.

     7. Disclaimer of Warranty. Unless required by applicable law or
        agreed to in writing, Licensor provides the Work (and each
        Contributor provides its Contributions) on an "AS IS" BASIS,
        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
        implied, including, without limitation, any warranties or conditions
        of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
        PARTICULAR PURPOSE. You are solely responsible for determining the
        appropriateness of using or redistributing the Work and assume any
        risks associated with Your exercise of permissions under this License.

     8. Limitation of Liability. In no event and under no legal theory,
        whether in tort (including negligence), contract, or otherwise,
        unless required by applicable law (such as deliberate and grossly
        negligent acts) or agreed to in writing, shall any Contributor be
        liable to You for damages, including any direct, indirect, special,
        incidental, or consequential damages of any character arising as a
        result of this License or out of the use or inability to use the
        Work (including but not limited to damages for loss of goodwill,
        work stoppage, computer failure or malfunction, or any and all
        other commercial damages or losses), even if such Contributor
        has been advised of the possibility of such damages.

     9. Accepting Warranty or Additional Liability. While redistributing
        the Work or Derivative Works thereof, You may choose to offer,
        and charge a fee for, acceptance of support, warranty, indemnity,
        or other liability obligations and/or rights consistent with this
        License. However, in accepting such obligations, You may act only
        on Your own behalf and on Your sole responsibility, not on behalf
        of any other Contributor, and only if You agree to indemnify,
        defend, and hold each Contributor harmless for any liability
        incurred by, or claims asserted against, such Contributor by reason
        of your accepting any such warranty or additional liability.

     END OF TERMS AND CONDITIONS

     APPENDIX: How to apply the Apache License to your work.

        To apply the Apache License to your work, attach the following
        boilerplate notice, with the fields enclosed by brackets "[]"
        replaced with your own identifying information. (Don't include
        the brackets!)  The text should be enclosed in the appropriate
        comment syntax for the file format. We also recommend that a
        file or class name and description of purpose be included on the
        same "printed page" as the copyright notice for easier
        identification within third-party archives.

     Copyright 2022 Jakob Bagterp

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.


pkgId: 6c8ab7f65bec337e7ac59a8baf972eddfad7673f734fd2355bac2a4cb6ddd367
name: python-browserpilot
arch: src
version: 0.2.52
epoch: 0
release: 1
summary: Natural language browser automation
url: https://pypi.org/project/browserpilot/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browserpilot-0.2.52-1.src.rpm
checksum_type: sha256
description:
  An intelligent web browsing agent controlled by natural language.

  ![demo](assets/demo_buffalo.gif)

  Language is the most natural interface through which humans give and receive instructions. Instead of writing bespoke automation or scraping code which is brittle to changes, creating and adding agents should be as simple as writing plain English.



  1. `pip install browserpilot`
  2. Download Chromedriver (latest stable release) from [here](https://sites.google.com/chromium.org/driver/) and place it in the same folder as this file. Unzip. In Finder, right click the unpacked chromedriver and click "Open". This will remove the restrictive default permissions and allow Python to access it.
  3. Create an environment variable in your favorite manner setting OPENAI_API_KEY to your API key.




  The form factor is fairly simple (see below).

  ```python
  from browserpilot.agents.gpt_selenium_agent import GPTSeleniumAgent

  instructions = """Go to Google.com
  Find all textareas.
  Find the first visible textarea.
  Click on the first visible textarea.
  Type in "buffalo buffalo buffalo buffalo buffalo" and press enter.
  Wait 2 seconds.
  Find all anchor elements that link to Wikipedia.
  Click on the first one.
  Wait for 10 seconds."""

  agent = GPTSeleniumAgent(instructions, "/path/to/chromedriver")
  agent.run()
  ```

  The harder (but funner) part is writing the natural language prompts.




  It helps if you are familiar with how Selenium works and programming in general. This is because this project uses GPT-3 to translate natural language into code, so you should be as precise as you can. In this way, it is more like writing code with Copilot than it is talking to a friend; for instance, it helps to refer to things as `input`s or `textareas` (vs. "text box" "search box") or "button which says 'Log in'" rather than "the login button". Sometimes, it will also not pick up on specific words that are important, so it helps to break them out into separate lines. Instead of "find all the visible textareas", you do "find all the textareas" and then "find the first visible textarea".

  You can look at some examples in `prompts/examples` to get started.

  Create "functions" by enclosing instructions in `BEGIN_FUNCTION func_name` and `END_FUNCTION`, and then call them by starting a line with `RUN_FUNCTION` or `INJECT_FUNCTION`. Below is an example:

  ```
  BEGIN_FUNCTION search_buffalo
  Go to Google.com
  Find all textareas.
  Find the first visible textarea.
  Click on the first visible textarea.
  Type in "buffalo buffalo buffalo buffalo buffalo" and press enter.
  Wait 2 seconds.
  Get all anchors on the page that contain the word "buffalo".
  Click on the first link.
  END_FUNCTION

  RUN_FUNCTION search_buffalo
  Wait for 10 seconds.
  ```

  You may also choose to create a yaml or json file with a list of instructions. In general, it needs to have an `instructions` field, and optionally a `compiled` field which has the processed code.

  See [buffalo wikipedia example](prompts/examples/buffalo_wikipedia.yaml).

  You may pass a `instruction_output_file` to the constructor of GPTSeleniumAgent which will output a yaml file with the compiled instructions from GPT-3, to avoid having to pay API costs.


  There are two ways I envision folks contributing.

  - **Adding to the Prompt Library**: Read "Writing Prompts" above and simply make a pull request to add something to `prompts/`! At some point, I will figure out a protocol for folder naming conventions and the evaluation of submitted code (for security, accuracy, etc). This would be a particularly attractive option for those who aren't as familiar with coding.
  - **Contributing code**: I am happy to take suggestions! The main way to add to the repository is to extend the capabilities of the agent, or to create new agents entirely. The best way to do this is to familiarize yourself with "Architecture and Prompt Patterns" above, and to (a) expand the list of capabilities in the base prompt in `InstructionCompiler` and (b) write the corresponding method in `GPTSeleniumAgent`.



  This repo was inspired by the work of [Yihui He](https://github.com/yihui-he/ActGPT), [Adept.ai](https://adept.ai/), and [Nat Friedman](https://github.com/nat/natbot). In particular, the basic abstractions and prompts used were built off of Yihui's hackathon code. The idea to preprocess HTML and use GPT-3 to intelligently pick elements out is from Nat.

  - The prompts used can be found in [instruction compiler](browserpilot/agents/compilers/instruction_compiler.py). The base prompt describes in plain English a set of actions that the browsing agent can take, some general conventions on how to write code, and some constraints on its behavior. **These actions correspond one-for-one with methods in `GPTSeleniumAgent`**. Those actions, to-date, include:
      - `env.driver`, the Selenium webdriver.
      - `env.find_elements(by='id', value=None)` finds and returns list of elements.
      - `env.find_element(by='id', value=None)` is similar to `env.find_elements()` except it only returns the first element.
      - `env.find_nearest(e, xpath)` can be used to locate an element near another one.
      - `env.send_keys(element, text)` sends `text` to element.
      - `env.get(url)` goes to url.
      - `env.click(element)` clicks the element.
      - `env.wait(seconds)` waits for `seconds` seconds.
      - `env.scroll(direction, iframe=None)` scrolls the page. Will switch to `iframe` if given. `direction` can be "up", "down", "left", or "right".
      - `env.get_llm_response(text)` asks AI about a string `text`.
      - `env.retrieve_information(prompt)` returns a string, information from a page given a prompt. Use prompt="Summarize:" for summaries. Invoked with commands like "retrieve", "find in the page", or similar.
      - `env.ask_llm_to_find_element(description)` asks AI to find an element that matches the description.
      - `env.query_memory(prompt)` asks AI with a prompt to query its memory (an embeddings index) of the web pages it has browsed. Invoked with "Query memory".
      - `env.save(text, filename)` saves the string `text` to a file `filename`.
      - `env.get_text_from_page()` returns the free text from the page.
  - The rest of the code is basically middleware which exposes a Selenium object to GPT-3. **For each action mentioned in the base prompt, there is a corresponding method in GPTSeleniumAgent.**
      - An `InstructionCompiler` is used to parse user input into semantically cogent blocks of actions.
  - The agent has a `Memory` which enables it to synthesize what it sees.



  0.2.51
  - Thanks to @rapatel0, you can now run BrowserPilot with Selenium Grid, remotely.

  -0.2.42 - 0.2.44
  - Small changes in `examples.py` and dependencies.
  - Refactor for the big Llama Index upgrade.

  0.2.38 - 0.2.41
  - Change `enable_memory` to `memory_file` to enable more control over what the memory is called. Allow users to load memory as well.
  - Make `get_text_from_page` simpler.


  0.2.26 - 0.2.37
  - Bit the bullet and switched the default model to gpt-3.5-turbo. Will be much cheaper!
  - Also fixed retries. I wasn't actually getting the retry action!
  - Fiddle with the prompt a bit for GPT-3.5.
  - Concerningly, gpt-3.5-turbo keep trying to import modules. I manually remove lines that try to import modules.
  - Compatibility with new Llama Index updates.

  0.2.14 - 0.2.25
  - Add options to avoid website detection of bots.
  - Add more OpenAI API error handling.
  - Improve stack trace prompt and a few other prompts.
  - Add "displayed in viewport" capability.
  - Make ```from browserpilot.agents import <agent>``` possible.
  - Make `find_element` and `find_elements` search only for displayed elements.
  - Save memory once finished running.
  - Add scroll option to top and bottom.

  0.2.10 - 0.2.13
  - Add more error handling for OpenAI exceptions.
  - Change all the embedding querying to use ChatGPT.
  - Get rid of the nltk dependency! Good riddance.
  - Expand the max token window for asking the LLM a question on a web page.
  - Fix an issue with the Memory module which tried to access OpenAI API key before it's initialized. Change the prompt slightly.
  - ❗️ Enable ChatGPT use with GPT Index, so that we can use GPT3.5-turbo to query embeddings.

  0.2.7 -  0.2.9
  - Vacillating on the default model. ChatGPT does not work well for writing code, as it takes too many freedoms with what it returns.
  - Also, I tried condensing the prompt a bit, which is growing a bit long.

  0.2.4 - 0.2.6
  - Give the agent a memory (still very experimental and not very good). Add capability to screenshot elements.
  - Bug fixes around versioning and prompt injection.

  0.2.3
  - Move `chrome_options` to somewhere more sensible. Just keep the yaml clean, you know?

  0.2.2
  - ChatGPT support.

  0.2.1
  - Dict support for loading instructions.

  0.2.0
  - 🎬 a `Studio` CLI which helps iteratively test prompts!
  - JSON loading.
  - Basic iframe support.

  <0.2.0
  - GPTSeleniumAgent should be able to load prompts and cached successful runs in the form of yaml files. InstructionCompiler should be able to save instructions to yaml.
  - 💭 Add a summarization capability to the agent.
  - Demo/test something where it has to ask the LLM to synthesize something it reads online.
  - 🚨 Figured out how to feed the content of the HTML page into the GPT-3 context window and have it reliably pick out specific elements from it, that would be great!



  This package runs code output from the OpenAI API in Python using `exec`. 🚨 **This is not considered a safe convention** 🚨. Accordingly, you should be extra careful when using this package. The standard disclaimer follows.

  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: bc42394bf87ad4845dc318f08105ba6b7908be1ddfc1971dcc1da42bfca01c8c
name: python-browserstack-local
arch: src
version: 1.2.8
epoch: 0
release: 1
summary: Python bindings for Browserstack Local
url: https://github.com/browserstack/browserstack-local-python
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browserstack-local-1.2.8-1.src.rpm
checksum_type: sha256
description:
  [![Build Status](https://travis-ci.org/browserstack/browserstack-local-python.svg?branch=master)](https://travis-ci.org/browserstack/browserstack-local-python)

  Python bindings for BrowserStack Local.



  ```sh
  pip install browserstack-local
  ```



  ```python
  from browserstack.local import Local


  bs_local = Local()


  bs_local_args = { "key": "<browserstack-accesskey>" }


  bs_local.start(**bs_local_args)


  print(bs_local.isRunning())


  bs_local.stop()

  ```



  Apart from the key, all other BrowserStack Local modifiers are optional. For the full list of modifiers, refer [BrowserStack Local modifiers](https://www.browserstack.com/local-testing#modifiers). For examples, refer below -


  To enable verbose logging -
  ```sh
  bs_local_args = { "key": "<browserstack-accesskey>" , "v": "true"}
  ```


  To test local folder rather internal server, provide path to folder as value of this option -
  ```sh
  bs_local_args = { "key": "<browserstack-accesskey>" , "f": "/my/awesome/folder"}
  ```


  To kill other running Browserstack Local instances -
  ```sh
  bs_local_args = { "key": "<browserstack-accesskey>" , "force": "true"}
  ```


  To disable local testing for Live and Screenshots, and enable only Automate -
  ```sh
  bs_local_args = { "key": "<browserstack-accesskey>" , "onlyAutomate": "true"}
  ```


  To route all traffic via local(your) machine -
  ```sh
  bs_local_args = { "key": "<browserstack-accesskey>" , "forcelocal": "true"}
  ```


  To use a proxy for local testing -

  * proxyHost: Hostname/IP of proxy, remaining proxy options are ignored if this option is absent
  * proxyPort: Port for the proxy, defaults to 3128 when -proxyHost is used
  * proxyUser: Username for connecting to proxy (Basic Auth Only)
  * proxyPass: Password for USERNAME, will be ignored if USERNAME is empty or not specified

  ```sh
  bs_local_args = { "key": "<browserstack-accesskey>", "proxyHost": "127.0.0.1", "proxyPort": "8000", "proxyUser": "user", "proxyPass": "password"}
  ```


  To use local proxy in local testing -

  * localProxyHost: Hostname/IP of proxy, remaining proxy options are ignored if this option is absent
  * localProxyPort: Port for the proxy, defaults to 8081 when -localProxyHost is used
  * localProxyUser: Username for connecting to proxy (Basic Auth Only)
  * localProxyPass: Password for USERNAME, will be ignored if USERNAME is empty or not specified

  ```
  bs_local_args = { "key": "<browserstack-accesskey>", "localProxyHost": "127.0.0.1", "localProxyPort": "8000", "-localProxyUser": "user", "-localProxyPass": "password"}
  ```


  To use PAC (Proxy Auto-Configuration) in local testing -

  * pac-file: PAC (Proxy Auto-Configuration) file’s absolute path

  ```
  bs_local_args = { "key": "<browserstack-accesskey>" , "-pac-file": "<pac_file_abs_path>"}
  ```


  If doing simultaneous multiple local testing connections, set this uniquely for different processes -
  ```sh
  bs_local_args = { "key": "<browserstack-accesskey>" , "localIdentifier": "randomstring"}
  ```





  By default, BrowserStack local wrappers try downloading and executing the latest version of BrowserStack binary in ~/.browserstack or the present working directory or the tmp folder by order. But you can override these by passing the -binarypath argument.
  Path to specify local Binary path -
  ```sh
  bs_local_args = { "key": "<browserstack-accesskey>" , "binarypath": "/browserstack/BrowserStackLocal"}
  ```


  To save the logs to the file while running with the '-v' argument, you can specify the path of the file. By default the logs are saved in the local.log file in the present woring directory.
  To specify the path to file where the logs will be saved -
  ```sh
  bs_local_args = { "key": "<browserstack-accesskey>" , "v": "true", "logfile": "/browserstack/logs.txt"}
  ```



  To run the test suite run, `python -m unittest discover`.



  You can submit bug reports either in the Github issue tracker.

  Before submitting an issue please check if there is already an existing issue. If there is, please add any additional information give it a "+1" in the comments.

  When submitting an issue please describe the issue clearly, including how to reproduce the bug, which situations it appears in, what you expect to happen, what actually happens, and what platform (operating system and version) you are using.



  We love pull requests! We are very happy to work with you to get your changes merged in, however, please keep the following in mind.

  * Adhere to the coding conventions you see in the surrounding code.
  * Include tests, and make sure all tests pass.
  * Before submitting a pull-request, clean up the git history by going over your commits and squashing together minor changes and fixes into the corresponding commits. You can do this using the interactive rebase command.


pkgId: 58d4685cc12f0db09d0d2c7535e72077c5109fa539592464121296a07ad80d2c
name: python-browserstack-sdk
arch: src
version: 1.22.4
epoch: 0
release: 1
summary: Python SDK for browserstack selenium-webdriver tests
url: https://pypi.org/project/browserstack-sdk/
rpm_license: BrowserStack Software License Agreement
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-browserstack-sdk-1.22.4-1.src.rpm
checksum_type: sha256
description:
  The “Licensed Software” under this BrowserStack Software License Agreement (“Agreement”) shall be used by
  you only if You agree to the following terms and conditions. Downloading the Licensed Software and indicating
  your consent to the terms of this license constitutes a binding Agreement between BrowserStack and You. If
  you do not agree with all of the terms of this Agreement, you must not use the Licensed Software and you must
  delete all of copies of the Licensed Software from your computer, device and/or systems. These terms also apply
  to any updates or upgrades to the Licensed Software.
  1. License: This Licensed Software shall remain the property of BrowserStack at all times.. The Licensed
  Software is licensed, not sold. This Agreement only gives you some rights to use the Licensed Software.
  You may install and use any number of copies of the Licensed Software to develop and test your
  applications and distribution of the Licensed Software is limited to within your affiliates, employees and
  independent contractors who are not competitors of BrowserStack. .
  2. Restrictions: You will not (and will not permit any third party) to: (a) rent, lease, provide access to or
  sublicense the Licensed Software to a third party; (b) use the Licensed Software to provide, or incorporate
  the Licensed Software into, any product or service provided to a third party; (c) copy or modify the
  Licensed Software or any Documentation, or create any derivative work from any of the foregoing; (d)
  remove or obscure any proprietary or other notices contained in the Licensed Software; or (e) You may
  not reverse engineer, decompile, disassemble, modify, translate, or attempt to discover the source code of
  the Licensed Software; (f) You may not work around any technical limitation in the Licensed Software;
  (g) distribute, resell, or provide the Licensed Software for use, copying or modification to any competitors
  of BrowserStack; or (h) You may use the Licensed Software along with the BrowserStack Services on the
  BrowserStack platform only.
  3. Usage Data: You agree and acknowledge through this Agreement that BrowserStack will collect data such
  as, but not limited to, use logs and error messages while using the Licensed Software.
  4. Term and Termination: This Agreement shall be for the term agreed to in the Terms or Service or Master
  SAAS Subscription Agreement or any other Agreement entered into between the You and BrowserStack
  for sue of BrowserStack Services and testing platform. BrowserStack can terminate this Agreement for
  convenience by providing seven (7) days’ notice to You or may terminate upon immediate effect if You
  commit a material breach of this Agreement.
  5. Confidentiality: All features and codes of the Licensed Software shall remain confidential. You
  understand that any violation or breach of this term of the Agreement may cause irreparable damages to
  BrowserStack. Thus, nothing in this Agreement shall limit Your liability with regard to violation of this
  Clause.
  6. DISCLAIMER OF WARRANTY. THE LICENSED SOFTWARE IS LICENSED “AS-IS.” YOU BEAR
  THE RISK OF USING IT. BROWSERSTACK GIVES NO EXPRESS WARRANTIES, GUARANTEES
  OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS,
  BROWSERSTACK EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  7.  LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. YOU CAN RECOVER
  FROM BROWSERSTACK AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $1. YOU
  CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS,
  SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.
  8. Indemnity: You are required to indemnify Browserstack for breach of any obligations and terms set forth
  under this Agreement.
  9. Export Restrictions. You must comply with all domestic and international export laws and regulations that
  apply to the Licensed Software, which include restrictions on destinations, end users, and end use.
  10. ENTIRE AGREEMENT. This Agreement, and the terms for supplements, updates, Internet-based
  services and support services that you use, are the entire Agreement for the Licensed Software and
  support services.
  11. APPLICABLE LAW. The laws and courts of State of California applies to interpretation of and claims
  for breach of this Agreement.
  Description: Python SDK for browserstack selenium-webdriver tests
  Keywords: browserstack,selenium,python
  Platform: UNKNOWN


pkgId: eb3aa9d14a8f3995900ba7d7a86226afeadc25713bc305a9fdf5456c0ce08879
name: python-brq
arch: src
version: 0.5.0
epoch: 0
release: 1
summary: brq
url: https://pypi.org/project/brq/
rpm_license: BSD 3-Clause License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brq-0.5.0-1.src.rpm
checksum_type: sha256
description:
  ![](https://img.shields.io/github/license/wh1isper/brq)
  ![](https://img.shields.io/github/v/release/wh1isper/brq)
  ![](https://img.shields.io/docker/image-size/wh1isper/brq)
  ![](https://img.shields.io/pypi/dm/brq)
  ![](https://img.shields.io/github/last-commit/wh1isper/brq)
  ![](https://img.shields.io/pypi/pyversions/brq)
  [![codecov](https://codecov.io/github/b-scheduler/brq/graph/badge.svg?token=84A7BQZIS2)](https://codecov.io/github/b-scheduler/brq)



  `brq` is a lightweight python library for job queue based on the redis stream, with no central server and self-organized by `Consumer`.

  ![Architecture.png](./assets/Architecture.png)



  Redis >= 6.2, tested with latest redis 6/7 docker image. Recommended to use redis>=7, which includes more inspection features.



  `pip install brq`



  > See [examples](./examples) for running examples.

  - Defer job and automatic retry error job
  - Dead queue for unprocessable job, you can process it later
  - Multiple consumers in one consumer group
  - No scheduler needed, consumer handles itself
  - Using callback function to process job result or exception



  If using `BrqConfig`(for example, `@task`), you can use a `.env` file and environment variables to configure brq. The prefix of environment variables is `BRQ_`.

  > For example, `BRQ_REDIS_PORT=6379 python consumer.py` for specifying redis port.

  See [configs](./brq/configs.py) for more details.





  ```python
  import os

  from brq.producer import Producer
  from brq.configs import BrqConfig


  async def main():
      config = BrqConfig()
      async with config.open_redis_client() as async_redis_client:
          await Producer(
              async_redis_client,
              redis_prefix=config.redis_key_prefix,
              redis_seperator=config.redis_key_seperator,
              max_message_len=config.producer_max_message_length,
          ).run_job("echo", ["hello"])


  if __name__ == "__main__":
      import asyncio

      asyncio.run(main())
  ```



  The only thing you need is `@task`, and the target function can be `sync` or `async` and `sync` function will be converted to `async` function and run in a thread automatically.

  ```python
  from brq import task


  @task
  def echo(message):
      print(f"Received message: {message}")


  if __name__ == "__main__":
      
      

      
      echo.serve()
  ```

  This is the same as the following, the classic way...But more flexible.

  ```python
  import os

  from brq.consumer import Consumer
  from brq.daemon import Daemon
  from brq.tools import get_redis_client, get_redis_url


  async def echo(message):
      print(message)


  async def main():
      redis_url = get_redis_url(
          host=os.getenv("REDIS_HOST", "localhost"),
          port=int(os.getenv("REDIS_PORT", 6379)),
          db=int(os.getenv("REDIS_DB", 0)),
          cluster=bool(os.getenv("REDIS_CLUSTER", "false") in ["True", "true", "1"]),
          tls=bool(os.getenv("REDIS_TLS", "false") in ["True", "true", "1"]),
          username=os.getenv("REDIS_USERNAME", ""),
          password=os.getenv("REDIS_PASSWORD", ""),
      )
      async with get_redis_client(redis_url) as async_redis_client:
          daemon = Daemon(Consumer(async_redis_client, echo))
          await daemon.run_forever()


  if __name__ == "__main__":
      import asyncio

      asyncio.run(main())
  ```



  We can use `defer_until` as a `datetime` or `defer_hours`+`defer_minutes`+`defer_seconds` to calculate a timestamp based on current redis timestamp. And use `unique` to set the job to be unique or not.

  By default, `unique=True` means `Job` with the **exactly** same `function_name`, `args` and `kwargs` will be unique, which allows the same `Job` to add into the deferred queue more than once. In this case, we differentiate tasks by the current redis timestamp(`Job.create_at`) and an additional uuid(`Job.uid`), just like `redis stream` did.

  If `unique=False`, the same `Job` will be added into the deferred queue only once. Duplicates will update the job's defer time. In this case, you can use your own uuid in `args`(or `kwargs`) to differentiate `Job`.



  Install pre-commit before commit

  ```
  pip install pre-commit
  pre-commit install
  ```

  Install package locally

  ```
  pip install -e .[test]
  ```

  Run unit-test before PR

  ```
  pytest -v
  ```


pkgId: d93190b2a60c071ee66be05e75d62160c3614cb52d28776d717a31dafd5afa6d
name: python-brreg
arch: src
version: 1.1.0
epoch: 0
release: 1
summary: API client for Brønnøysundregistrene.
url: https://github.com/crdbrd/python-brreg
rpm_license: Apache-2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brreg-1.1.0-1.src.rpm
checksum_type: sha256
description:
  `python-brreg`is a Python library for interacting with the open APIs of the
  Norwegian Business Registry, [Brønnøysundregistrene](https://www.brreg.no/).

  The library requires Python 3.8 or newer.
  The library can be installed from [PyPI](https://pypi.org/project/brreg/):
  ```
  python3 -m pip install brreg
  ```

  - [Documentation](https://brreg.readthedocs.io/)
  - [Source code](https://github.com/crdbrd/python-brreg)
  - [Releases](https://github.com/crdbrd/python-brreg/releases)
  - [Issue tracker](https://github.com/crdbrd/python-brreg/issues)
  - [Contributors](https://github.com/crdbrd/python-brreg/graphs/contributors)


  The `brreg.enhetsregisteret` part of this library wraps the open
  [Enhetsregistret API](https://data.brreg.no/enhetsregisteret/api/docs/index.html).
  This is a list of all features this library could implement on top of this API.
  However, I will not attempt to make the project cover all parts of
  Brønnøysundregisterene's API. I am open to requests, so that time is spent on
  the parts of the API that there is an actual demand for.
  - Enheter
    - Search - Implemented
    - Get one by organization number - Implemented
    - Get one's roles by organization number - Implemented
    - Get all updates since given time - Request if needed
  - Underenheter
    - Search - Implemented
    - Get one by organization number - Implemented
    - Get all updates since given time - Request if needed
  - Organisasjonsform
    - Get all - Request if needed
  - Rolletype
    - Get all - Request if needed
    - Get one - Request if needed
  - Rollegruppetype
    - Get all - Request if needed
    - Get one - Request if needed
  - Representant
    - Get all - Request if needed
    - Get one - Request if needed
  - Kommuner
    - Get all - Request if needed
  - Matrikkelenhet
    - Get one by matrikkelnummer - Request if needed
    - Get one by matrikkelenhet-ID - Request if needed

  Copyright
  2019 [Otovo ASA](https://www.otovo.com/),
  2023-2024 [Cardboard AS](https://cardboard.inc/).
  Licensed under the
  [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0).


pkgId: 61185d36c68e56a4930ec264ddc9aac1448b2028b639b77c7b007de0ff40e15f
name: python-brreg
arch: src
version: 1.2.0
epoch: 0
release: 1
summary: API client for Brønnøysundregistrene.
url: https://github.com/crdbrd/python-brreg
rpm_license: Apache-2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brreg-1.2.0-1.src.rpm
checksum_type: sha256
description:
  `python-brreg`is a Python library for interacting with the open APIs of the
  Norwegian Business Registry, [Brønnøysundregistrene](https://www.brreg.no/).

  The library requires Python 3.9 or newer.
  The library can be installed from [PyPI](https://pypi.org/project/brreg/):
  ```
  python3 -m pip install brreg
  ```

  - [Documentation](https://brreg.readthedocs.io/)
  - [Source code](https://github.com/crdbrd/python-brreg)
  - [Releases](https://github.com/crdbrd/python-brreg/releases)
  - [Issue tracker](https://github.com/crdbrd/python-brreg/issues)
  - [Contributors](https://github.com/crdbrd/python-brreg/graphs/contributors)


  The `brreg.enhetsregisteret` part of this library wraps the open
  [Enhetsregistret API](https://data.brreg.no/enhetsregisteret/api/docs/index.html).
  This is a list of all features this library could implement on top of this API.
  However, I will not attempt to make the project cover all parts of
  Brønnøysundregisterene's API. I am open to requests, so that time is spent on
  the parts of the API that there is an actual demand for.
  - Enheter
    - Search - Implemented
    - Get one by organization number - Implemented
    - Get one's roles by organization number - Implemented
    - Get all updates since given time - Request if needed
  - Underenheter
    - Search - Implemented
    - Get one by organization number - Implemented
    - Get all updates since given time - Request if needed
  - Organisasjonsform
    - Get all - Request if needed
  - Rolletype
    - Get all - Request if needed
    - Get one - Request if needed
  - Rollegruppetype
    - Get all - Request if needed
    - Get one - Request if needed
  - Representant
    - Get all - Request if needed
    - Get one - Request if needed
  - Kommuner
    - Get all - Request if needed
  - Matrikkelenhet
    - Get one by matrikkelnummer - Request if needed
    - Get one by matrikkelenhet-ID - Request if needed

  Copyright
  2019 [Otovo ASA](https://www.otovo.com/),
  2023-2024 [Cardboard AS](https://cardboard.inc/).
  Licensed under the
  [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0).


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


  Computes the deep size of an object.


  Defines some fancy print functions


  Functions to handle download and extract files


  Returns the number of lines of the given file




  * **Melchior du Lac**
  * **Joan Hérisson**



  brs-utils is released under the MIT licence. See the LICENCE file for details.


pkgId: e4d4fb79b86a6d20388dcd52bba50c96edab36f8c086b28386347e0450059cfa
name: python-bruce-models
arch: src
version: 0.0.2
epoch: 0
release: 1
url: https://pypi.org/project/bruce-models/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-bruce-models-0.0.2-1.src.rpm
checksum_type: sha256
summary:
  This is a library which defines data-models for the Nextspace API and provides functions for communicating with the endpoints.

description:
  This is a library which defines data-models for the Nextspace API and provides functions for communicating with the endpoints.



  - `pip install .`

  - `python ./public/main.py` (to test it loads after build)



  - `python -m build`


pkgId: 99d4b6fbc7934809c2499653746bf5d50a9f6ea2387858f0d7e0f7f8e52feec9
name: python-bruce-models
arch: src
version: 0.0.3
epoch: 0
release: 1
url: https://pypi.org/project/bruce-models/
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-bruce-models-0.0.3-1.src.rpm
checksum_type: sha256
summary:
  This is a library which defines data-models for the Nextspace API and provides functions for communicating with the endpoints.

description:
  This is a library which defines data-models for the Nextspace API and provides functions for communicating with the endpoints.


pkgId: 033b6ab869c83ef131f1b63d4ad2cf3a59472ad6a0ade16825a6ecc6570ab4ef
name: python-bruhanimate
arch: src
version: 0.2.89
epoch: 0
release: 1
summary: ASCII Termnial Animation Package
url: https://github.com/ethanlchristensen/bruhanimate
rpm_license: Apache License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-bruhanimate-0.2.89-1.src.rpm
checksum_type: sha256
description:
  [![Downloads](https://static.pepy.tech/badge/bruhanimate)](https://pepy.tech/project/bruhanimate)
  [![Downloads](https://static.pepy.tech/badge/bruhanimate/month)](https://pepy.tech/project/bruhanimate)
  [![Downloads](https://static.pepy.tech/badge/bruhanimate/week)](https://pepy.tech/project/bruhanimate)
  <div>
  <img src="https://github.com/user-attachments/assets/22d61f3e-b3ca-406f-9e1c-2f539eea23c7" alt="snow" border="0">
  <img src="https://github.com/user-attachments/assets/644afa91-ffb0-465e-815f-998a59759c3b" alt="fireworks" border="0">
  </div>

  [![Supported Python versions](https://img.shields.io/pypi/pyversions/termcolor.svg?logo=python&logoColor=FFE873)](https://pypi.org/project/bruhanimate/)

  bruhanimate provides a set of tools for creating and rendering animations directly in the terminal. Designed for ease of use, this package enables developers to incorporate dynamic animations into command-line applications. While drawing inspiration from existing terminal animation libraries, bruhanimate brings a fresh approach and offers a unique set of features tailored for flexibility and creativity in terminal-based projects.

  Inspired by the <a href="https://github.com/peterbrittain/asciimatics">Asciimatics</a> package.





  ```bash
  pip install --upgrade bruhanimate
  ```



  ```bash
  git clone https://github.com/FNBBDevs/bruhanimate
  cd bruhanimate
  python -m pip install .
  ```


  Use some of the built in demos to see what is possible. There are demos for each effect. Simply import `<effect>_demo` from bruhanimate and call the `<effect>_demo.run()` to run the demo!
  - static
  - offset
  - noise
  - stars
  - snow
  - rain
  - plasma
  - gol (Conway's Game of Life)
  - matrix
  - twinkle

  ```py

  from bruhanimate import plasma_demo

  plasma_demo.run()
  ```


  Here are some examples on how bruhanimate might be used. <br/><br/>

  Pass in arguments through the `show()` command. <br/>
  ```py

  """
  Here is a simple program that uses the EffectRenderer passing in
  the arguments to the main function
  """
  from bruhanimate import Screen, CenterRenderer, images


  def demo(screen, img, frames, time, effect_type, background, transparent):
      renderer = CenterRenderer(screen, frames, time, img, effect_type, background, transparent)
      renderer.update_smart_transparent(True)
      renderer.effect.update_color(True)
      renderer.effect.update_intensity(100)
      renderer.run()


  def main():
      Screen.show(demo, args=(images.get_image("twopoint"), 300, 0, "noise", " ", False))


  if __name__ == "__main__":
      main()
  ```

  Set the arguments directly in the function invoked by `show()`. <br/>
  ```py
  """
  Here is a simple program that uses the EffectRenderer setting the arguments
  directly in the main function.
  """
  from bruhanimate import Screen, EffectRenderer


  def demo(screen: Screen):
      renderer = EffectRenderer(
          screen=screen,
          frames=float("inf"),
          frame_time=0.1,
          effect_type="snow",
          background=" ",
          transparent=False
      )
      renderer.run()


  if __name__ == "__main__":
      Screen.show(main)
  ```


pkgId: 24e52d447278be562c68769f7845286f31321b3b7f9bc1e3a6270eae9a6d4d58
name: python-bruhcolor
arch: src
version: 0.0.64
epoch: 0
release: 1
summary: 256 Color Terminal Text Formatter
url: https://pypi.org/project/bruhcolor/
rpm_license: UNKNOWN
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-bruhcolor-0.0.64-1.src.rpm
checksum_type: sha256
description:
  [![Supported Python versions](https://img.shields.io/pypi/pyversions/termcolor.svg?logo=python&logoColor=FFE873)](https://pypi.org/project/bruhcolor/)
  [![Downloads](https://static.pepy.tech/badge/bruhcolor)](https://pepy.tech/project/bruhcolor)
  [![Downloads](https://static.pepy.tech/badge/bruhcolor/month)](https://pepy.tech/project/bruhcolor)
  [![Downloads](https://static.pepy.tech/badge/bruhcolor/week)](https://pepy.tech/project/bruhcolor)
  [![PyPI version](https://badge.fury.io/py/bruhcolor.svg)](https://badge.fury.io/py/bruhcolor)
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)

  bruhcolor is a Python package that allows you to color text in the terminal. It supports both 8-color and 256-color formatting, providing a wide range of colors to choose from. The package is available on PYPI and is licensed under the MIT license.



  To install bruhcolor, you can use pip:

  ```shell
  pip install bruhcolor
  ```



  To use bruhcolor, simply import the `bruhcolored` function from the package:

  ```python
  from bruhcolor import bruhcolored
  ```

  You can then use the `bruhcolored` function to color your text. Here's an example:

  ```python
  colored_text = bruhcolored("Hello world!", color="red", on_color=194, attrs=["bold", "blink"])

  print(colored_text)
  ```

  This will output the text "Hello world!" in red color, with a background color of 194 and the attributes "bold" and "blink" applied.



  bruhcolor supports a wide range of colors. You can use either the 8-color or 256-color formatting. Here are some examples of available colors:

  - 8-color: black, grey, red, green, yellow, blue, magenta, cyan, light_grey, dark_grey, light_red, light_green, light_yellow, light_blue, light_magenta, light_cyan, white
  - 256-color: You can use any number between 0 and 255 to specify a color.

  To see a full list of available colors, you can use the `colors` function:

  ```python
  from bruhcolor import colors

  colors(support="full")
  ```

  This will print out all the available colors.



  bruhcolor also supports various attributes that you can apply to your text. Here are some examples of available attributes:

  - bold
  - dark
  - italic
  - underline
  - blink
  - reverse
  - concealed
  - crossed-out

  To see a full list of available attributes, you can use the `valid_effects` function:

  ```python
  from bruhcolor import valid_effects

  valid_effects()
  ```

  This will print out all the available attributes.



  bruhcolor is licensed under the MIT License. See [LICENSE](https://github.com/FNBBDevs/bruhcolor/blob/main/COPYING.txt) for more information.


pkgId: 95b9752efc01600954018b80502ab93ddfc0b61554a3a3dfb9e7d8a428d9c046
name: python-brukeropus
arch: src
version: 1.1.0
epoch: 0
release: 1
url: https://github.com/joshduran/brukeropus
rpm_license: None
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brukeropus-1.1.0-1.src.rpm
checksum_type: sha256
summary:
  A python package for communicating with Bruker OPUS spectroscopy software and reading its binary file format.

description:
  `brukeropus` is a Python package for interacting with Bruker's OPUS spectroscopy software. Currently, the package can
  read OPUS data files and communicate/control OPUS through the DDE interface (e.g. for scripting measurement sequences).

  `brukeropus` can read the binary data files saved by OPUS. The parsing algorithm in this package is more complete than
  previous efforts, with a goal to achieve 100% extraction accuracy.

  - Extracts spectral data (e.g. sample, reference, absorbance, transmittance, etc.)
  - Extracts 3D spectral data (e.g. spectral time series)
  - Extracts file metadata (e.g. beamsplitter, source, aperture, etc.)
  - Very fast data parsing and assigning to `OPUSFile` class (limited by disk I/O)
  - Low-level parsing functions are well documented and could be used to build your own custom OPUS file class if
  `OPUSFile` does not suit your needs)

  ```python
  from brukeropus import read_opus
  from matplotlib import pyplot as plt

  opus_file = read_opus('file.0')  # Returns an OPUSFile class

  opus_file.print_parameters()  # Pretty prints all metadata in the file to the console

  if 'a' in opus_file.data_keys:  # If absorbance spectra was extracted from file
      plt.plot(opus_file.a.x, opus_file.a.y)  # Plot absorbance spectra
      plt.title(opus_file.sfm + ' - ' + opus_file.snm)  # Sets plot title to Sample Form - Sample Name
      plt.show()  # Display plot
  ```

  - While all metadata can be be extracted as key: val pairs, the keys are stored as three characters (e.g. BMS, SRT, SRC)
  and are not particularly descriptive.  This package has human readable labels for over 100 of these metadata keys, but
  it is not complete.

      - OPUS software should be using a local file (perhaps PARMTEXT.bin) to convert these keys to human readable lables.
      it would be ideal to extract these labels directly from this file rather than manually adding them by hand as is
      currently done.

  - I have only tested this on ~5000 files generated in my lab (all very similiar) as well as a handful of files I've
  found online (most of which had some error when being read by other tools). This package is capable of reading all of
  those files, but thorough testing on a wide variety of files is incomplete.

      - If you have a file that cannot be read by `brukeropus`, please open an issue with a description about the file and
      what seems to be failing.  Also provide a link for me to download the file.  Make sure the file can be read by OPUS
      first (i.e. if the file is corrupted and unreadable by OPUS then `brukeropus` will not be able to read it either).

  `brukeropus` can send commands and perform queries to an OPUS software instance through the DDE communication protocol.
  OPUS must be open and logged in on the same PC where `brukeropus` is called from to operate.

  - Initiate a sample or reference measurement
  - Change/define measurement parameters prior to performing measurement (useful for sweeping parameters like aperture
  size, mirror velocity, etc.)
  - Send commands for interacting with motors and other accessories (e.g. moving mirrors, rotating polarizers, etc.)
  - Control vacuum operation for vacuum-equipped spectrometers (e.g. Vertex 80V FTIR)
  - Unload files from OPUS software (so they can be unlocked for moving, renaming, etc.)

  ```python
  from brukeropus import opus, read_opus
  from matplotlib import pyplot as plt

  opus = Opus()  # Connects to actively running OPUS software

  apt_options = opus.get_param_options('apt') # Get all valid aperture settings

  for apt in apt_options[2:-2]: # Loop over all but the two smallest and two largest aperature settings
      filepath = opus.measure_sample(apt=apt, nss=10, unload=True) # Perform measurement and unload file from OPUS
      data = read_opus(filepath) # Read OPUS file from measurement
      plt.plot(data.sm.x, data.sm.y, label=apt) # Plot single-channel sample spectra
  plt.legend()
  plt.show()
  ```

  - Continue to improve the file reader towards 100% compliance
  - Parse "PARMTEXT.BIN" file to extract all parameter labels and setup options
  - Add a basic GUI for browsing OPUS files

  **Requirements**
  - Python 3.6+
  - numpy

  **Optional**
  - matplotlib (for plotting examples)

  ```python
  pip install brukeropus
  ```

  https://joshduran.github.io/brukeropus/brukeropus.html


pkgId: 71b35cc3133f096b0e03843dfa4068c8b8a1cfe2f5e9dc4a8221a0f7ebc19b86
name: python-brunel
arch: src
version: 2.6.2
epoch: 0
release: 1
summary: Brunel Visualization For Jupyter/IPython Notebooks
url: https://pypi.org/project/brunel/
rpm_license: Apache Software License 2.0
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brunel-2.6.2-1.src.rpm
checksum_type: sha256
description:
  Brunel defines a highly succinct and novel language that produces interactive data visualizations using ``pandas DataFrame`` objects. The language is well suited for both data scientists and more aggressive business users. The system interprets the language syntax and produces live visualizations directly within Jupyter notebooks.
  * Articles and notes on Brunel can be found in the `brunelvis.org <http://www.brunelvis.org>`_ blog.  Videos are available on `YouTube <https://www.youtube.com/channel/UClXE1IhLQs6NpdMd0X8jALA>`_.
  * Details about the language can be found in the `Brunel Language Tutorial <http://brunel.mybluemix.net/docs>`_
  * Examples can be found in the `Brunel Visualization Gallery  <https://github.com/Brunel-Visualization/Brunel/wiki>`_ and the `Brunel Visualization Cookbook <https://github.com/Brunel-Visualization/Brunel/wiki/Brunel-Visualization-Cookbook>`_.
  * See the `Release Change Log <https://github.com/Brunel-Visualization/Brunel/blob/master/CHANGELOG.md>`_ for new features and changes.
  Please report any issues on our `Github  <https://github.com/Brunel-Visualization/Brunel>`_
  site.  Q&A available on `Gitter  <https://gitter.im/Brunel-Visualization/Brunel>`_


pkgId: 33f487984f7d64ff7c31778f3276fb2f727afef910516d3dc288f642c546e8d6
name: python-brunns-matchers
arch: src
version: 2.7.0
epoch: 0
release: 1
summary: Custom PyHamcrest matchers
url: https://github.com/brunns/brunns-matchers/
rpm_license: MIT License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brunns-matchers-2.7.0-1.src.rpm
checksum_type: sha256
description:
  Various custom [PyHamcrest](https://pyhamcrest.readthedocs.io) matchers.

  [![made-with-python](https://img.shields.io/badge/Made%20with-Python-1f425f.svg)](https://www.python.org/)
  [![Build Status](https://travis-ci.org/brunns/brunns-matchers.svg?branch=master&logo=travis)](https://travis-ci.org/brunns/brunns-matchers)
  [![PyPi Version](https://img.shields.io/pypi/v/brunns-matchers.svg?logo=pypi)](https://pypi.org/project/brunns-matchers/#history)
  [![Python Versions](https://img.shields.io/pypi/pyversions/brunns-matchers.svg?logo=python)](https://pypi.org/project/brunns-matchers/)
  [![Licence](https://img.shields.io/github/license/brunns/brunns-matchers.svg)](https://github.com/brunns/brunns-matchers/blob/master/LICENSE)
  [![GitHub all releases](https://img.shields.io/github/downloads/brunns/brunns-matchers/total.svg?logo=github)](https://github.com/brunns/brunns-matchers/releases/)
  [![GitHub forks](https://img.shields.io/github/forks/brunns/brunns-matchers.svg?label=Fork&logo=github)](https://github.com/brunns/brunns-matchers/network/members)
  [![GitHub stars](https://img.shields.io/github/stars/brunns/brunns-matchers.svg?label=Star&logo=github)](https://github.com/brunns/brunns-matchers/stargazers/)
  [![GitHub watchers](https://img.shields.io/github/watchers/brunns/brunns-matchers.svg?label=Watch&logo=github)](https://github.com/brunns/brunns-matchers/watchers/)
  [![GitHub contributors](https://img.shields.io/github/contributors/brunns/brunns-matchers.svg?logo=github)](https://github.com/brunns/brunns-matchers/graphs/contributors/)
  [![GitHub issues](https://img.shields.io/github/issues/brunns/brunns-matchers.svg?logo=github)](https://github.com/brunns/brunns-matchers/issues/)
  [![GitHub issues-closed](https://img.shields.io/github/issues-closed/brunns/brunns-matchers.svg?logo=github)](https://github.com/brunns/brunns-matchers/issues?q=is%3Aissue+is%3Aclosed)
  [![GitHub pull-requests](https://img.shields.io/github/issues-pr/brunns/brunns-matchers.svg?logo=github)](https://github.com/brunns/brunns-matchers/pulls)
  [![GitHub pull-requests closed](https://img.shields.io/github/issues-pr-closed/brunns/brunns-matchers.svg?logo=github)](https://github.com/brunns/brunns-matchers/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aclosed)
  [![Codacy Badge](https://api.codacy.com/project/badge/Grade/0b22e28c2ebe4722899a07c4cfa5bc69)](https://www.codacy.com/app/brunns/brunns-matchers)
  [![Codacy Coverage](https://api.codacy.com/project/badge/coverage/0b22e28c2ebe4722899a07c4cfa5bc69)](https://www.codacy.com/app/brunns/brunns-matchers)
  [![Lines of Code](https://tokei.rs/b1/github/brunns/brunns-matchers)](https://github.com/brunns/brunns-matchers)



  Install with pip:

      pip install brunns-matchers

  (As usual, use of a [venv](https://docs.python.org/3/library/venv.html) or [virtualenv](https://virtualenv.pypa.io) is recommended.)



  Requires [tox](https://tox.readthedocs.io). Run `make precommit` tells you if you're OK to commit. For more options, run:

      make help



  Requires [hub](https://hub.github.com/), [setuptools](https://setuptools.readthedocs.io), [wheel](https://pypi.org/project/wheel/) and [twine](https://twine.readthedocs.io). To release `n.n.n`:

  ```sh
  version="n.n.n" # Needs to match new version number in setup.py.
  git checkout -b "release-$version"
  make precommit && git commit -am"Release $version" && git push --set-upstream origin "release-$version" # If not already all pushed, which it should be.
  hub release create "V$version" -t"release-$version" -m"Version $version"
  python setup.py sdist bdist_wheel
  twine upload dist/*$version*
  git checkout master
  git merge "release-$version"
  ```


pkgId: 3c2e6bc6b6c025bb131f7b74641ea9628ac69ea0c79e47625e150371648bf377
name: python-brunns-row
arch: src
version: 2.1.0
epoch: 0
release: 1
summary: Convenience wrapper for DB API and csv.DictReader rows, and similar.
url: https://brunns-row.readthedocs.io
rpm_license: MIT License
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brunns-row-2.1.0-1.src.rpm
checksum_type: sha256
description:
  Convenience wrapper for DB API and csv.DictReader rows, and similar, inspired by [Greg Stein](https://github.com/gstein)'s lovely [dtuple module](https://code.activestate.com/recipes/81252-using-dtuple-for-flexible-query-result-access/).

  [![made-with-python](https://img.shields.io/badge/Made%20with-Python-1f425f.svg)](https://www.python.org/)
  [![Build Status](https://travis-ci.org/brunns/brunns-row.svg?branch=master&logo=travis)](https://travis-ci.org/brunns/brunns-row)
  [![PyPi Version](https://img.shields.io/pypi/v/brunns-row.svg?logo=pypi)](https://pypi.org/project/brunns-row/#history)
  [![Python Versions](https://img.shields.io/pypi/pyversions/brunns-row.svg?logo=python)](https://pypi.org/project/brunns-row/)
  [![Licence](https://img.shields.io/github/license/brunns/brunns-row.svg)](https://github.com/brunns/brunns-row/blob/master/LICENSE)
  [![GitHub all releases](https://img.shields.io/github/downloads/brunns/brunns-row/total.svg?logo=github)](https://github.com/brunns/brunns-row/releases/)
  [![GitHub forks](https://img.shields.io/github/forks/brunns/brunns-row.svg?label=Fork&logo=github)](https://github.com/brunns/brunns-row/network/members)
  [![GitHub stars](https://img.shields.io/github/stars/brunns/brunns-row.svg?label=Star&logo=github)](https://github.com/brunns/brunns-row/stargazers/)
  [![GitHub watchers](https://img.shields.io/github/watchers/brunns/brunns-row.svg?label=Watch&logo=github)](https://github.com/brunns/brunns-row/watchers/)
  [![GitHub contributors](https://img.shields.io/github/contributors/brunns/brunns-row.svg?logo=github)](https://github.com/brunns/brunns-row/graphs/contributors/)
  [![GitHub issues](https://img.shields.io/github/issues/brunns/brunns-row.svg?logo=github)](https://github.com/brunns/brunns-row/issues/)
  [![GitHub issues-closed](https://img.shields.io/github/issues-closed/brunns/brunns-row.svg?logo=github)](https://github.com/brunns/brunns-row/issues?q=is%3Aissue+is%3Aclosed)
  [![GitHub pull-requests](https://img.shields.io/github/issues-pr/brunns/brunns-row.svg?logo=github)](https://github.com/brunns/brunns-row/pulls)
  [![GitHub pull-requests closed](https://img.shields.io/github/issues-pr-closed/brunns/brunns-row.svg?logo=github)](https://github.com/brunns/brunns-row/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aclosed)
  [![Codacy Badge](https://api.codacy.com/project/badge/Grade/6f43e871d3514176bebc650849ac7d4a)](https://www.codacy.com/app/brunns/brunns-row)
  [![Codacy Coverage](https://api.codacy.com/project/badge/coverage/6f43e871d3514176bebc650849ac7d4a)](https://www.codacy.com/app/brunns/brunns-row)
  [![Documentation Status](https://readthedocs.org/projects/brunns-row/badge/?version=latest)](https://brunns-row.readthedocs.io/en/latest/?badge=latest)
  [![Lines of Code](https://tokei.rs/b1/github/brunns/brunns-row)](https://github.com/brunns/brunns-row)



  Install with pip:

      pip install brunns-row

  (As usual, use of a [venv](https://docs.python.org/3/library/venv.html) or [virtualenv](https://virtualenv.pypa.io) is recommended.)



  The basic approach is to create a wrapper object from some kind of description - typically a
  [DBAPI cursor](https://www.python.org/dev/peps/pep-0249/#cursor-objects)'s
  [description](https://www.python.org/dev/peps/pep-0249/#description), or a
  [csv.DictReader](https://docs.python.org/3/library/csv.html#csv.DictReader)'s
  [fieldnames](https://docs.python.org/3/library/csv.html#csv.csvreader.fieldnames) attribute - then to use the wrapper's
  `wrap(row)` method to wrap each row. `wrap(row)` returns an object from which you can access the row's fields as
  attributes. A couple of simple examples:



  ```python
  cursor = conn.cursor()
  cursor.execute("SELECT kind, rating FROM sausages ORDER BY rating DESC;")
  wrapper = RowWrapper(cursor.description)
  rows = [wrapper.wrap(row) for row in cursor.fetchall()]
  for row in rows:
      print(row.kind, row.rating)
  ```



  ```python
  reader = csv.DictReader(csv_file)
  wrapper = RowWrapper(reader.fieldnames)
  rows = [wrapper.wrap(row) for row in reader]
  for row in rows:
      print(row.kind, row.rating)
  ```

  Attributes names are simply the column names where possible, converted to valid identifiers where necessary by replacing
  invalid characters with "\_"s, prefixing any leading numerics with "a\_", and de-duplicating where necessary by adding
  numeric suffixes.



  Requires [tox](https://tox.readthedocs.io). Run `make precommit` tells you if you're OK to commit. For more options, run:

      make help



  Requires [hub](https://hub.github.com/), [setuptools](https://setuptools.readthedocs.io),
  [wheel](https://github.com/pypa/wheel) and [twine](https://twine.readthedocs.io). To release version `n.n.n`, first
  update the version number in `setup.py`, then:

  ```sh
  version="n.n.n" # Needs to match new version number in setup.py.
  git checkout -b "release-$version"
  make precommit && git commit -am"Release $version" && git push --set-upstream origin "release-$version" # If not already all pushed, which it should be.
  hub release create "V$version" -t"release-$version" -m"Version $version"
  python setup.py sdist bdist_wheel
  twine upload dist/*$version*
  git checkout master
  git merge "release-$version"
  ```


pkgId: 53e403a680ac1b628619d42b030e1972607ff5372ef12e8dc2e0e65e888fb357
name: python-brunt
arch: src
version: 1.2.0
epoch: 0
release: 1
summary: Unofficial python SDK for Brunt, this package allows you to control your Brunt devices from code.
url: https://github.com/eavanvalkenburg/brunt-api
rpm_license: mit
rpm_group: Unspecified
rpm_buildhost: localhost
location_href: Packages/python-brunt-1.2.0-1.src.rpm
checksum_type: sha256
description:
  [![PyPI version](https://badge.fury.io/py/brunt.svg)](https://badge.fury.io/py/brunt)


  Unofficial python SDK for Brunt, based on the NPM version here https://github.com/MattJeanes/brunt-api

  This package allows you to control your Brunt devices from code.



  This script shows the usage and how to use the output of the calls, off course if you already know the name of your device you do not need to call getThings.

  This script checks the current position of a blind called 'Blind' and if that is 100 (fully open), sets it to 90 and vice versa.

  ```python
  from brunt import BruntClient, BruntClientAsync

  bapi = BruntClient()

  print("Calling Brunt")

  bapi.login('username', 'password')

  print("    Logged in, gettings things.")

  things = bapi.get_things()['things']

  print(f"    { len(things) } thing(s) found.")

  state = bapi.get_state(thing='Blind')['thing']

  print(f"    Current status of { state['NAME'] } is position { state['currentPosition'] }")
  newPos = 100
  if int(state['currentPosition']) == 100:
      newPos = 90
  print(f"    Setting { state['NAME'] } to position { newPos }")

  res = bapi.change_request_position(newPos, thing='Blind')

  print('    Success!' if res else '    Fail!')

  ```
  <h1 id="brunt.BruntClient">BruntClient & BruntClientAsync</h1>

  ```python
  from brunt import BruntClient
  BruntClient(username, password)

  or

  from brunt import BruntClientAsync
  BruntClientAsync(username, password, session)
  ```
  Constructor for the API wrapper.

  If you supply username and password here, they are stored, but not used.
  Auto logging in then does work when calling another method, no explicit login needed.

  :param username: the username of your Brunt account
  :param password: the password of your Brunt account

  Async only :param session: aiohttp.ClientSession object

  <h2 id="brunt.BruntClient.login">login</h2>

  ```python
  BruntClient.login(self, username, password)
  await BruntClient.async_login(self, username, password)
  ```
  Login method using username and password

  :param username: the username of your Brunt account
  :param password: the password of your Brunt account

  :return: True if successful
  :raises: errors from Requests call

  <h2 id="brunt.brunt.BruntClient.getThings">get_things</h2>

  ```python
  BruntClient.get_things(self)
  await BruntClient.async_get_things(self)
  ```
  Get the things registered in your account

  :return: List of Things
  :raises: errors from Requests call

  <h2 id="brunt.brunt.BruntClient.getState">get_state</h2>

  ```python
  BruntClient.get_state(self, thing="Blind")
  await BruntClient.async_get_state(self, thing="Blind")
  ```
  Get the state of a thing, by NAME or thingUri

  :param thing: a string with the NAME of the thing, which is then checked against the names of all the things.
  :param thingUri: Uri (string) of the thing you are getting the state from, not checked against getThings.

  :return: a Thing.
  :raises: ValueError if the requested thing does not exists. NameError if not logged in. SyntaxError when
      not exactly one of the params is given.

  <h2 id="brunt.brunt.BruntClient.changeRequestPosition">change_request_position</h2>

  ```python
  BruntClient.change_request_position(self, request_position, thing="Blind")
  await BruntClient.async_change_request_position(self, request_position, thing="Blind")
  ```
  Changes the position of the thing. Internally calls the changeKey method with key set to
  requestPosition and value set to request_position

  :param request_position: The new position for the slide (0-100)
  :param thing: a string with the name of the thing, which is then checked against the names of all the things.
  :param thingUri: Uri (string) of the thing you are getting the state from, not checked against getThings.

  :return: a dict with 'result'.
  :raises: ValueError if the requested thing does not exists or the position is not between 0 and 100.
      NameError if not logged in. SyntaxError when not exactly one of the params is given.

  <h2 id="brunt.brunt.BruntClient.changeKey">change_key</h2>

  ```python
  BruntClient.change_key(self, key="requestPosition", value="100", thing="Blind")
  await BruntClient.async_change_key(self, key="requestPosition", value="100", thing="Blind")
  ```
  Change a variable of the thing by supplying the key and value. Mostly included for future additions.

  :param key: The key of the value you want to change
  :param value: The new value
  :param thing: a string with the name of the thing, which is then checked using getThings.
  :param thingUri: Uri (string) of the thing you are getting the state from, not checked against getThings.
  :return: a dict with 'result'.
  :raises: ValueError if the requested thing does not exists or the position is not between 0 and 100.
      NameError if not logged in. SyntaxError when not exactly one of the params is given.


