# Dosage

[![CI](https://github.com/webcomics/dosage/actions/workflows/ci.yaml/badge.svg)](https://github.com/webcomics/dosage/actions/workflows/ci.yaml)
[![Code Climate](https://codeclimate.com/github/webcomics/dosage/badges/gpa.svg)](https://codeclimate.com/github/webcomics/dosage)
[![codecov](https://codecov.io/gh/webcomics/dosage/branch/master/graph/badge.svg)](https://codecov.io/gh/webcomics/dosage)
![Maintenance](https://img.shields.io/maintenance/yes/2024.svg)
![License](https://img.shields.io/github/license/webcomics/dosage)

Dosage is designed to keep a local copy of specific webcomics and other
picture-based content such as Picture of the Day sites. With the dosage
commandline script you can get the latest strip of a webcomic, or catch-up to
the last strip downloaded, or download a strip for a particular date/index (if
the webcomic's site layout allows this).

Multiple webcomics can be downloaded in parallel, making the update of comic
strips faster.

Dosage is licensed under the [MIT license](COPYING)

## Notice

This software is in no way intended to publically "broadcast" comic strips, it
is purely for personal use. Please be aware that by making downloaded strips
publically available (without the explicit permission of the author) you may be
infringing upon various copyrights.

Additionally, Dosage respects the robots.txt exclusion protocol. This makes
sure no content is accessed in an automatic way without consent by the
publishers.

In any case, you should support the authors of the comics you are downloading,
either by buying some of their products or even donating them some money since
they provide the comics you like and read.

If you are a publisher of comics and want Dosage to access your files,
add the following entry to your robots.txt file:

    User-agent: Dosage
    Allow: *

## Usage

List available comics (ca. 3000 at the moment):

    $ dosage --list

Get the latest comic of for example CalvinAndHobbes and save it in the "Comics"
directory:

    $ dosage CalvinAndHobbes

If you already have downloaded several comics and want to get the latest strip
of all of them:

    $ dosage @

To help others find good comics, you can vote for your favourite ones:

    $ dosage --vote @

For advanced options and features execute `dosage --help`.

### Adult content

Some comics contain adult content and require age confirmation. These comics
can only be downloaded by using the `--adult` option, which confirms that you
are old enough to view them.

## Installation

### Dependencies

Since dosage is written in [Python](http://www.python.org/), a Python
installation is required: Dosage needs at least Python 3.8. Dosage requires
some Python modules from PyPI, so installation with `pip` is recommended.

### Using the Windows binary

Windows users can download a complete binary (including Python) from the
[release page].

[release page]: https://github.com/webcomics/dosage/releases/latest

### Install with pipx

The simplest way to install and upgrade dosage is with [pipx]. To install the
newest stable version with all optional features use:

    pipx install dosage[css,bash]

To install the newest development version, use:

    pipx install "dosage[css,bash] @ git+https://github.com/webcomics/dosage.git"

To upgrade such installations, just run:

    pipx upgrade dosage

### Installation for development

If you want to run dosage directly from the source code, you should install
it in "[editable]" mode, preferable in a [virtual environment]:

    pip install -e .[css,bash,dev]

After that, `dosage` should be available as a normal command.

[pipx]: https://github.com/pipxproject/pipx
[editable]: https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs
[virtual environment]: https://docs.python.org/3/library/venv.html

## Reporting Bugs

You can report bugs, patches or requests at the [GitHub issue
tracker](https://github.com/webcomics/dosage/issues) - Dosage currently
supports a large number of comics and that number grows on a regular basis. If
you feel that there are comics that Dosage does not currently support, but
should support, please feel free to request them.

## Extending Dosage

In order to add a new webcomic, a new module class has to be created in one of
the *.py files in one  the `dosagelib/plugins` subdirectory. Look at the
[documentation for adding modules](doc/adding_new_comics.md) and at
existing module classes for examples.

### Test suite status

Dosage has unit tests to ensure code quality. GitHub Actions are used for
continuous build and test integration. See the badges at the top of this page
for the current status.


<img src="https://github.com/spectacles-ci/spectacles/raw/master/docs/img/logo.png" width="600">

[![CircleCI](https://circleci.com/gh/spectacles-ci/spectacles.svg?style=svg)](https://circleci.com/gh/spectacles-ci/spectacles)
[![downloads](https://img.shields.io/pypi/dm/spectacles)](https://img.shields.io/pypi/dm/spectacles)

## What is Spectacles?

**[Spectacles](https://spectacles.dev/?utm_source=github&utm_medium=readme) is a continuous integration tool for Looker and LookML.** Spectacles runs **validators** which perform a range of tests on your Looker instance and your LookML. Each validator interacts with the Looker API to run tests that ensure your Looker instance is running smoothly.

From the command line, you can run the following validators as subcommands (e.g. `spectacles sql`):

✅ [**SQL** validation](https://docs.spectacles.dev/cli/tutorials/validators#the-sql-validator) - tests the `sql` field of each dimension for database errors

✅ [**Assert** validation](https://docs.spectacles.dev/cli/tutorials/validators#the-assert-validator) - runs [Looker data tests](https://docs.looker.com/reference/model-params/test)

✅ [**Content** validation](https://docs.spectacles.dev/cli/tutorials/validators#the-content-validator) - tests for errors in Looks and Dashboards

✅ [**LookML** validation](https://docs.spectacles.dev/cli/tutorials/validators/#the-lookml-validator) - runs [LookML validator](https://cloud.google.com/looker/docs/lookml-validation)

## Installation

Spectacles CLI is distributed on PyPi and is easy to install with pip:

```bash
pip install spectacles
```

> 📣 You can also use Spectacles as a **full-service web application**! Check out **[our website](https://spectacles.dev/?utm_source=github&utm_medium=readme)** to learn more.

## Documentation

You can find detailed documentation for the CLI and web app on our docs page: [docs.spectacles.dev](https://docs.spectacles.dev/cli/tutorials/getting-started).

## Why we built this

Occasionally, when we make changes to LookML or our data warehouse, we break downstream experiences in Looker:

* Changing the name of a database column without changing the corresponding `sql` field in our Looker view, leaving our users with a database error when using that field
* Adding an invalid join to an explore that fans out our data, inflating a key metric that drives our business without realising
* Editing LookML without remembering to check the Content Validator for errors, disrupting Dashboards and Looks that our users rely on
* Giving a new dimension a confusing name, causing other developers in our team to spend extra time trying to figure out how it should be used

**We believe in the power of testing and continuous integration for analytics.** We believe that automated tests should catch these errors before they're ever pushed to production.

We wanted a single tool to perform these checks for us, so we built Spectacles to enhance the business intelligence layer of analytics CI pipelines.

## Community

Have a question or just want to chat Spectacles or Looker? [Join us in Slack.](https://join.slack.com/t/spectacles-ci/shared_invite/zt-akmm4mo6-XnPcUUaG3Z5~giRc_5JaUQ)


# ApprovalTests.Python

## Contents

  * [What can I use ApprovalTests for?](#what-can-i-use-approvaltests-for)
  * [Getting Started](#getting-started)
    * [What Are Approvals](#what-are-approvals)
    * [New Projects](#new-projects)
      * [Minimal Example Tutorial](#minimal-example-tutorial)
    * [Adding to Existing Projects](#adding-to-existing-projects)
  * [Overview](#overview)
    * [Example using pytest](#example-using-pytest)
    * [Example using unittest](#example-using-unittest)
    * [Example using CLI](#example-using-cli)
      * [Usage](#usage)
      * [Argument Definitions](#argument-definitions)
  * [Reporters](#reporters)
    * [Selecting a Reporter](#selecting-a-reporter)
    * [JSON file for collection of reporters](#json-file-for-collection-of-reporters)
  * [Support and Documentation](#support-and-documentation)
    * [Missing Documentation?](#missing-documentation)
    * [Dependencies](#dependencies)
      * [Required dependencies](#required-dependencies)
      * [Extra dependencies](#extra-dependencies)
  * [For developers](#for-developers)
    * [Weekly Ensemble](#weekly-ensemble)
    * [Pull Requests](#pull-requests)

Capturing Human Intelligence - ApprovalTests is an open source assertion/verification library to aid testing.
`approvaltests` is the ApprovalTests port for Python.

For more information see: [www.approvaltests.com](http://approvaltests.com/).

[![PyPI version](https://img.shields.io/pypi/v/approvaltests.svg)](https://pypi.org/project/approvaltests)
[![Python versions](https://img.shields.io/pypi/pyversions/approvaltests.svg)](https://pypi.org/project/approvaltests)
[![Build Status](https://github.com/approvals/ApprovalTests.Python/workflows/Test/badge.svg?branch=master)](https://github.com/approvals/ApprovalTests.Python/actions)
[![Build Status](https://github.com/approvals/ApprovalTests.Python/workflows/on-push-do-doco/badge.svg)](https://github.com/approvals/ApprovalTests.Python/actions?query=workflow%3Aon-push-do-doco)
[![Build Status](https://github.com/approvals/ApprovalTests.Python/workflows/Upload%20Python%20Package/badge.svg)](https://github.com/approvals/ApprovalTests.Python/actions?query=workflow%3A%22Upload+Python+Package%22)

## What can I use ApprovalTests for?

You can use ApprovalTests to verify objects that require more than a simple assert including long strings, large arrays,
and complex hash structures and objects. ApprovalTests really shines when you need a more granular look at the test
failure. Sometimes, trying to find a small difference in a long string printed to STDOUT is just too hard!
ApprovalTests solves this problem by providing reporters which let you view the test results in one of many popular diff
utilities.

## Getting Started

### What Are Approvals

If you need to gain a better understanding or are new to this concept, start [here](https://github.com/approvals/ApprovalTests.Documentation/blob/main/explanations/what_are_approvals.md).

### New Projects

If you are starting a new project, we suggest you use the [Starter Project](https://github.com/approvals/ApprovalTests.Python.StarterProject).
You can just clone this and go. It's great for exercises, katas, and green field projects.

#### Minimal Example Tutorial

If this is first time approvaltesting in python, consider starting here: [Minimal Example Tutorial](docs/tutorial/minimal-example.md)

### Adding to Existing Projects

From [pypi](https://pypi.org/project/approvaltests/):

    pip install approvaltests

## Overview

Approvals work by comparing the test results to a golden master. If no golden master exists you can create a snapshot
of the current test results and use that as the golden master. The reporter helps you manage the golden master.
Whenever your current results differ from the golden master, Approvals will launch an external application for you to
examine the differences. Either you will update the master because you expected the changes and they are good,
or you will go back to your code and update or roll back your changes to get your results back in line with the
golden master.

### Example using pytest

```py
from approvaltests.approvals import verify

def test_simple():
    result = "Hello ApprovalTests"
    verify(result)
```
snippet source | anchor

Install the plugin pytest-approvaltests and use it to select a reporter:

    pip install pytest-approvaltests
    pytest --approvaltests-use-reporter='PythonNative'

The reporter is used both to alert you to changes in your test output, and to provide a tool to update the golden
master. In this snippet, we chose the 'PythonNative' reporter when we ran the tests. For more information about selecting
reporters see [the documentation](https://github.com/approvals/ApprovalTests.Python.PytestPlugin)

### Example using unittest

```py
import unittest

from approvaltests.approvals import verify

class GettingStartedTest(unittest.TestCase):
    def test_simple(self):
        verify("Hello ApprovalTests")

if __name__ == "__main__":
    unittest.main()
```
snippet source | anchor

This example has the same behaviour as the pytest version, but uses the built-in test framework `unittest` instead.

### Example using CLI

You can invoke a verify() call from the command line. This allows invoking python approvals from any other stack via subprocesses.

#### Usage

```
python -m approvaltests --test-id hello --received "hello world!"
```

or

```
python -m approvaltests -t hello -r "hello world!"
```

or

```
echo "hello world!" | python -m approvaltests -t hello
```

#### Argument Definitions

-   **`--test-id`** or **`-t`**: Test identifier used to name the `approved.txt` and `received.txt` files for the test.

-   **`--received`** or **`-r`**: The output of the program under test (a string) that is passed to the verify method.

    -   **`stdin`**: Instead of providing a `received` argument, you may use `stdin`.

## Reporters

### Selecting a Reporter

All verify functions take an optional `options` parameter that can configure reporters (as well as many other aspects).

ApprovalTests.Python comes with a few reporters configured, supporting Linux, Mac OSX, and Windows.

In the example shown below, we pass in an options with a reporter we're selecting directly:

```py
class TestSelectReporterFromClass(unittest.TestCase):
    def test_simple(self):
        verify("Hello", options=Options().with_reporter(report_with_beyond_compare()))
```
snippet source | anchor

You can also use the `GenericDiffReporterFactory` to find and select the first diff utility that exists on our system.

An advantage of this method is you can modify the reporters.json file directly to handle your unique system.

```py
class TestSelectReporter(unittest.TestCase):
    def setUp(self):
        self.factory = GenericDiffReporterFactory()

    def test_simple(self):
        verify(
            "Hello", options=Options().with_reporter(self.factory.get("BeyondCompare"))
        )
```
snippet source | anchor

Or you can build your own GenericDiffReporter on the fly

```py
class GettingStartedTest(unittest.TestCase):
    def test_simple(self):
        verify(
            "Hello",
            options=Options().with_reporter(
                GenericDiffReporter.create(r"C:\my\favorite\diff\utility.exe")
            ),
        )
```
snippet source | anchor

As long as `C:/my/favorite/diff/utility.exe` can be invoked from the command line using the format `utility.exe file1 file2`
then it will be compatible with GenericDiffReporter. Otherwise you will have to derive your own reporter, which
we won't cover here.

### JSON file for collection of reporters

To wrap things up, I should note that you can completely replace the collection of reporters known to the reporter
factory by writing your own JSON file and loading it.

For example if you had `C:/myreporters.json`

```json
[
    ["BeyondCompare4", "C:/Program Files (x86)/Beyond Compare 4/BCompare.exe"],
    ["WinMerge", "C:/Program Files (x86)/WinMerge/WinMergeU.exe"],
    ["Tortoise", "C:/Program Files (x86)/TortoiseSVN/bin/tortoisemerge.exe"]
]
```

You could then use that file by loading it into the factory:

```python

import unittest

from approvaltests.approvals import verify
from approvaltests.reporters.generic_diff_reporter_factory import GenericDiffReporterFactory

class GettingStartedTest(unittest.TestCase):
    def setUp(self):
        factory = GenericDiffReporterFactory()
        factory.load('C:/myreporters.json')
        self.reporter = factory.get_first_working()

    def test_simple(self):
        verify('Hello', self.reporter)

if __name__ == "__main__":
    unittest.main()
```

Of course, if you have some interesting new reporters in `myreporters.json` then please consider updating the
`reporters.json` file that ships with Approvals and submitting a pull request.

## Support and Documentation

-   [Documentation](/docs/README.md)

-   GitHub: [https://github.com/approvals/ApprovalTests.Python](https://github.com/approvals/ApprovalTests.Python)

-   ApprovalTests Homepage: [http://www.approvaltests.com](http://www.approvaltests.com)

### Missing Documentation?

If there is documentation you wish existed, please add a `page request` to [this issue](https://github.com/approvals/ApprovalTests.Python/issues/135).

### Dependencies

ApprovalTests require Python 3.8 or greater and the following dependencies:

#### Required dependencies

These dependencies are always required for approvaltests

```txt
pytest>=4.0.0
empty-files>=0.0.3
typing_extensions>=3.6.2
```
snippet source | anchor

#### Extra dependencies

These dependencies are required if you are going to use the related functionality
If you want the bare minimum you can use the pypi project
[approvaltests-minimal](https://pypi.org/project/approvaltests-minimal/)

```txt
pyperclip>=1.5.29     # For Clipboard Reporter
beautifulsoup4>=4.4.0 # For verify_html
allpairspy>=2.1.0     # For PairwiseCombinations
mrjob>=0.7.4          # For MrJob
testfixtures >= 7.1.0 # For verify_logging
mock >= 5.1.0         # For verify_logging
```
snippet source | anchor

## For developers

### Weekly Ensemble

The best way to contribute is to [join our weekly mob/ensemble](./docs/Contribute.md)

### Pull Requests

Pull requests are welcomed, particularly those accompanied by automated tests.

To run the self-tests:
`./run_tests.sh`

This will run the self-tests on several python versions. We support python 3.8 and above.

All pull requests will be pre-checked using GitHub actions to execute all these tests. You can see the [results of test
runs here](https://github.com/approvals/ApprovalTests.Python/actions).


# IBM Storage Scale CSI (Container Storage Interface)

[Official IBM Documentation](https://www.ibm.com/docs/en/spectrum-scale-csi)

The IBM Storage Scale Container Storage Interface (CSI) project enables container orchestrators, such as Kubernetes and OpenShift, to manage the life-cycle of persistent storage.

This project contains an [go-based operator](https://sdk.operatorframework.io) to run and manage the deployment of the IBM Storage Scale CSI Driver.

## Support

IBM Storage Scale CSI driver is part of the IBM Storage Scale offering. Please follow the [IBM support procedure](https://www.ibm.com/mysupport/s/) for any issues with the driver.

## Report Bugs

For help with urgent situations, please use the IBM PMR process.  All IBM Storage Scale customers using CSI,
who also have ongoing support contracts, are entitled to the PMR process.  Feature requests through the official RFE channels are also encouraged.

For non-urgent issues, suggestions, recommendations, feel free to open an issue in [github](https://github.com/IBM/ibm-spectrum-scale-csi/issues).
Issues will be addressed as team availability permits.

## Contributing

We welcome contributions to this project, see [Contributing](CONTRIBUTING.md) for more details.

##### Note: This repository includes contributions from [ubiquity](https://github.com/ibm/ubiquity).

## Licensing

Copyright 2022, 2024 IBM Corp.

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.


![BusyLight Project Logo][LOGO]

![version][pypi-version]
![monthly-downloads][monthly-downloads]
![visits][visits]
![supported python versions][python-versions]
![license][license]
![Code style: black][code-style-black]

[![pytest-linux](https://github.com/JnyJny/busylight/actions/workflows/pytest-linux.yaml/badge.svg)](https://github.com/JnyJny/busylight/actions/workflows/pytest-linux.yaml)
[![MacOS](https://github.com/JnyJny/busylight/actions/workflows/pytest-macos.yaml/badge.svg)](https://github.com/JnyJny/busylight/actions/workflows/pytest-macos.yaml)
[![pytest-windows](https://github.com/JnyJny/busylight/actions/workflows/pytest-windows.yaml/badge.svg)](https://github.com/JnyJny/busylight/actions/workflows/pytest-windows.yaml)

[BusyLight for Humans™][0] gives you control of USB attached LED
lights from a variety of vendors. Lights can be controlled via
the command-line, using a HTTP API or imported directly into your own
Python project.

![All Supported Lights][DEMO]
Flag1,
Busylight Alpha2,
Status Indicator3,
Blink(1)4,
Mute5,
Blynclight6.
Orb7,
BusyLight Omega8,
BlinkStick Square9,
Blynclight Mini10,
MuteMe Original11,
fit-statUSB12,
MuteSync13,
Blynclight Plus14

## Features
- Control lights from the [command-line][HELP].
- Control lights via a [Web API][WEBAPI].
- Import `busylight` into your own Python project.
- Supported on MacOS and Linux
- Windows support is untested but there are reports that it is working.
- Supports _nine_ vendors & sixteen devices:

| **Vendor** | | | | |
|------------:|---|---|---|---|
| [**Agile Innovative**][2] | BlinkStick Square |
| [**Compulab**][8] | fit-statUSB |
| [**Embrava**][3] | Blynclight | Blynclight Mini | Blynclight Plus |
| [**Kuando**][4] | Busylight Alpha | BusyLight Omega |
| [**Luxafor**][5] | Bluetooth | Flag | Mute | Orb |
| [**Plantronics**][3] | Status Indicator |
| [**MuteMe**][7] | MuteMe Original | Mute Mini |
| [**MuteSync**][9] | MuteSync |
| [**ThingM**][6] | Blink(1) |

If you have a USB light that's not on this list open an issue with:
 - the make and model device you want supported
 - where I can get one
 - any public hardware documentation you are aware of

Or even better, open a pull request!

### Gratitude

Thank you to [@todbot][todbot] and the very nice people at [ThingM][thingm] who
graciously and unexpectedly gifted me with two `blink(1) mk3` lights!

## Basic Install

Installs only the command-line `busylight` tool and associated
modules.

```console
$ python3 -m pip install busylight-for-humans
```

## Web API Install

Installs `uvicorn` and `FastAPI` in addition to `busylight`:

```console
$ python3 -m pip install busylight-for-humans[webapi]
```

## Development Install

I use the tool [poetry][poetry-docs] to manage various aspects of this project, including:
- dependencies
- pytest configuration
- versioning
- optional dependencies
- virtual environment creation
- building packages
- publishing packages to PyPi

```console
$ python3 -m pip install poetry
$ cd path/to/busylight
$ poetry shell
<venv> $ poetry install -E webapi
<venv> $ which busylight
<venv> $ which busyserve
```

After installing into the virtual environment, the project is now available in editable mode.  Changes made in the source will be reflected in the runtime behavior when running in the poetry initiated shell.

## Linux Post-Install Activities

Linux controls access to USB devices via the [udev subsystem][UDEV]. By
default it denies non-root users access to devices it doesn't
recognize. I've got you covered!

You'll need root access to configure the udev rules:

```console
$ busylight udev-rules -o 99-busylights.rules
$ sudo cp 99-busylights.rules /etc/udev/rules.d
$ sudo udevadm control -R
$ # unplug/plug your light
$ busylight on
```

## Command-Line Examples

```console
$ busylight on               # light turns on green
$ busylight on red           # now it's shining a friendly red
$ busylight on 0xff0000      # still red
$ busylight on #00ff00       # now it's blue!
$ busylight blink            # it's slowly blinking on and off with a red color
$ busylight blink green fast # blinking faster green and off
$ busylight --all on         # turn all lights on green
$ busylight --all off        # turn all lights off
```

## HTTP API Examples

First start the `busylight` API server using the `busyserv` command line interface:
```console
$ busyserve -D
INFO:     Started server process [40064]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
...
```

The API is fully documented and available via these URLs:

- `https://localhost:8000/redoc`
- `https://localhost:8000/docs`

Now you can use the web API endpoints which return JSON payloads:

```console
  $ curl -s http://localhost:8000/lights/status | jq
  ...

  $ curl -s http://localhost:8000/light/0/status | jq
  ...

  $ curl -s http://localhost:8000/light/0/on | jq
  {
    "light_id": 0,
    "action": "on",
    "color": "green",
    "rgb": [0, 128, 0]
  }

  $ curl -s http://localhost:8000/light/0/off | jq
  {
    "light_id": 0,
    "action": "off"
  }

  $ curl -s http://localhost:8000/light/0/on?color=purple | jq
  {
    "light_id": 0,
    "action": "on",
    "color": "purple",
    "rgb": [128, 0, 128]
  }

  $ curl -s http://localhost:8000/lights/on | jq
  {
    "light_id": "all",
    "action": "on",
    "color": "green",
    "rgb", [0, 128, 0]
  }

  $ curl -s http://localhost:8000/lights/off | jq
  {
    "light_id": "all",
    "action": "off"
  }

  $ curl -s http://localhost:8000/lights/rainbow | jq
  {
    "light_id": "all",
    "action": "effect",
    "name": "rainbow"
  }
```

### Authentication
The API can be secured with a simple username and password through
[HTTP Basic Authentication][BASICAUTH]. To require authentication
for all API requests, set the `BUSYLIGHT_API_USER` and
`BUSYLIGHT_API_PASS` environmental variables before running
`busyserve`.

> :warning: **SECURITY WARNING**: HTTP Basic Auth sends usernames and passwords in *cleartext* (i.e., unencrypted). Use of SSL is highly recommended!

## Code Examples

Adding light support to your own python applications is easy!

### Simple Case: Turn On a Single Light

In this example, we pick an Embrava Blynclight to activate with
the color white. Colors are specified as a three-tuple of integers
that range from 0 to 255 and represent red, green, and blue
in that order.

```python
from busylight.lights.embrava import Blynclight

light = Blynclight.first_light()

light.on((255, 255, 255))

light.off()
```

Not sure what light you've got? No problem!

```python
from busylight.lights import Light

light = Light.first_light()

light.on((0xff, 0, 0xff))

light.off()
```

### Slightly More Complicated

The `busylight` package includes a manager class that's great for
working with multiple lights or lights that require a little
more direct intervention like the Kuando Busylight family.

```python
from busylight.manager import LightManager
from busylight.effects import Effects

manager = LightManager()
for light in manager.lights:
   print(light.name)

rainbow = Effects.for_name("spectrum")(duty_cycle=0.05)

manager.apply_effect(rainbow)
...
manager.off()
```

[0]: https://github.com/JnyJny/busylight

[2]: https://github.com/JnyJny/busylight/blob/master/docs/devices/agile_innovative.md
[3]: https://github.com/JnyJny/busylight/blob/master/docs/devices/embrava.md
[4]: https://github.com/JnyJny/busylight/blob/master/docs/devices/kuando.md
[5]: https://github.com/JnyJny/busylight/blob/master/docs/devices/luxafor.md
[6]: https://github.com/JnyJny/busylight/blob/master/docs/devices/thingm.md
[7]: https://github.com/JnyJny/busylight/blob/master/docs/devices/muteme.md
[8]: https://github.com/JnyJny/busylight/blob/master/docs/devices/compulab.md
[9]: https://github.com/JnyJny/busylight/blob/master/docs/devices/mutesync.md

[LOGO]: https://github.com/JnyJny/busylight/blob/master/docs/assets/BusyLightForHumans.png
[HELP]: https://github.com/JnyJny/busylight/blob/master/docs/busylight.1.md
[WEBAPI]: https://github.com/JnyJny/busylight/blob/master/docs/busylight_api.pdf

[DEMO]: https://github.com/JnyJny/busylight/blob/master/docs/assets/HerdOfLights.png

[BASICAUTH]: https://en.wikipedia.org/wiki/Basic_access_authentication
[UDEV]: https://en.wikipedia.org/wiki/Udev

[todbot]: https://github.com/todbot
[thingm]: https://thingm.com

[code-style-black]: https://img.shields.io/badge/code%20style-black-000000.svg
[pypi-version]: https://img.shields.io/pypi/v/busylight-for-humans
[python-versions]: https://img.shields.io/pypi/pyversions/busylight-for-humans
[license]: https://img.shields.io/pypi/l/busylight-for-humans
[dependencies]: https://img.shields.io/librariesio/github/JnyJny/busylight
[monthly-downloads]: https://img.shields.io/pypi/dm/busylight-for-humans
[poetry-docs]: https://python-poetry.org/docs/
[visits]: https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2FJnyJny%2Fbusylight&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=Visits&edge_flat=false


# modlunky2

[![Python Testing](https://github.com/spelunky-fyi/modlunky2/actions/workflows/test.yml/badge.svg)](https://github.com/spelunky-fyi/modlunky2/actions/workflows/test.yml)
[![Latest Release](https://img.shields.io/github/release/spelunky-fyi/modlunky2.svg?style=flat)](https://github.com/spelunky-fyi/modlunky2/releases/latest)
![Downloads](https://img.shields.io/github/downloads/spelunky-fyi/modlunky2/total.svg?style=flat)

Modlunky 2 is a tool for creating and using mods related to Spelunky 2. It offers

* Mod management, including
  * Downloading and updating mods from spelunky.fyi
  * Launching Spelunky 2 with mods (via Playlunky)
* Creating and editing levels
* Extracting assets (e.g. images and audio)
* Updating and launching Overlunky
* Speedrun trackers

## Usage

Follow the instructions in the [Modlunky 2 Wiki](https://github.com/spelunky-fyi/modlunky2/wiki).

> :warning: Spelunky 2 doesn't officially support modding. Do not report modding related bugs to Blitworks.

## Contributing

The [documentation for contributing](CONTRIBUTING.md) explains

* How to report bugs
* Where to discuss changes
* Setup for development

## Contributors

Special thanks to the following contributors for helping make modlunky possible:

* `garebear`
* `SciresM`
* `Cloppershy`
* `iojonmbnmb`
* `Dregu`
* `JackHasWifi`
* `mriswithe`
* `Malacath`
* `MauveAlert`


# ![ChRIS logo](https://github.com/FNNDSC/ChRIS_ultron_backEnd/blob/master/docs/assets/logo_chris.png) ChRIS\_ultron\_backEnd

[![Build](https://github.com/FNNDSC/ChRIS_ultron_backEnd/actions/workflows/ci.yml/badge.svg)](https://github.com/FNNDSC/ChRIS_ultron_backEnd/actions/workflows/ci.yml)
[![License](https://img.shields.io/github/license/fnndsc/ChRIS_ultron_backEnd.svg)](./LICENSE)

_ChRIS_ is an open-source platform for containerized medical compute.
The _ChRIS_ backend, a.k.a. _ChRIS Ultron Backend_ or _**CUBE**_ for short,
is a component of the _ChRIS_ system.

![Architecture Diagram](https://chrisproject.org/img/figures/ChRIS_architecture.svg#gh-light-mode-only)
![Architecture Diagram](https://chrisproject.org/img/figures/ChRIS_architecture_dark.svg#gh-dark-mode-only)

The core backend service for the ChRIS distributed software platform, also known by the anacronym _CUBE_. Internally the service is implemented as a Django-PostgreSQL project offering a [collection+json](http://amundsen.com/media-types/collection/) REST API. Important ancillary components include the ``pfcon`` and ``pman`` file transfer and remote process management microservices.

## ChRIS development, testing and deployment

### Abstract

_ChRIS Ultron Back End_ (sometimes also _ChRIS Underlying Back End_) or simply _CUBE_ is the main core of the ChRIS system. _CUBE_ provides the main REST API to the ChRIS system, as well as maintaining an internal database of users, files, pipelines, and plugins. Currently _CUBE_ has two separate compute paradigms depending on deployment context. In the case of _development_ all components of _CUBE_ use `docker` and `docker swarm` technologies. In the case of _production_ technologies such as `openshift` and `kubernetes` are also supported.

Consult this page for instructions on starting _CUBE_ in either _development_ or _production_ contexts. For documentation/overview/background, please see the [documention](https://github.com/FNNDSC/ChRIS_docs).

### Preconditions

#### Operating system support -- please read

##### Linux

Linux is the first class host platform for all things _CUBE_ related. Linux distributions used by various core developers include Ubuntu, Arch, and Fedora. The development team is happy to provide help to folks trying / struggling to run _CUBE_ on most any Linux distribution.

##### macOS

macOS is fully supported as a host platform for _CUBE_. Please note that you **must update/tweak some things first**. Most importantly, macOS is distributed with a deprecated version of the `bash` shell **that will not work with our Makefile**. If you want to host _CUBE_ on macOS, you **must** update `bash` to a current version. Instructions are out of scope of this document, but we recommend [homebrew](https://brew.sh) as your friend here.

##### Windows

In a word, **don't** (ok, that's technically two words). _CUBE_ is ideally meant to be deployed on Linux/*nix systems. **Windows is not officially supported nor recommended as the host environment**. If you insist on trying on Windows you can consult some unmaintained documentation on attempts to deploy _CUBE_ using the Windows Subsystem for Linux (WSL) [here](https://github.com/FNNDSC/CHRIS_docs/blob/master/workflows/ChRIS_on_WSL.asciidoc). This probably will break. Note that currently no one on the core development uses Windows in much of any capacity so interest or knowledge to help questions about Windows support is low. Nonetheless, we would welcome any brave soul though who has the time and inclination to fully investigate _CUBE_ on Windows deployment.

#### Install latest Docker and Docker Compose.

Currently tested platforms:
* ``Docker 18.06.0+``
* ``Docker Compose 1.27.0+``
* ``Ubuntu 18.04+ and MAC OS X 10.14+``

#### On a Linux machine make sure to add your computer user to the ``docker`` group

Consult this page https://docs.docker.com/engine/install/linux-postinstall/

### TL;DR

#### If you read nothing else on this page, and just want to get an instance of the ChRIS backend services up and running with no mess, no fuss:

##### The real TL;DR

The all in one copy/paste line to drop into your terminal (assuming of course you are in the repo directory and have the preconditions met):

```bash
docker swarm leave --force && docker swarm init --advertise-addr 127.0.0.1 &&  \
./unmake.sh && sudo rm -fr CHRIS_REMOTE_FS && rm -fr CHRIS_REMOTE_FS &&        \
./make.sh -U -I -i
```

This will start a **bare bones** _CUBE_. This _CUBE_ will **NOT** have any plugins installed. To install a set of plugins, do

```bash
./postscript.sh
```

##### Slightly longer but still short TL;DR

Start a local Docker Swarm cluster if not already started:

```bash
docker swarm init --advertise-addr 127.0.0.1
```

Get the source code from CUBE repo:

```bash
git clone https://github.com/FNNDSC/ChRIS_ultron_backend
cd ChRIS_ultron_backend
```

Run full CUBE instantiation with tests:
```bash
./unmake.sh ; sudo rm -fr CHRIS_REMOTE_FS; rm -fr CHRIS_REMOTE_FS; ./make.sh
```

Or skip unit and integration tests and the intro:
```bash
./unmake.sh ; sudo rm -fr CHRIS_REMOTE_FS; rm -fr CHRIS_REMOTE_FS; ./make.sh -U -I -s
```

Once the system is "up" you can add more compute plugins to the ecosystem:

```bash
./postscript.sh
```

The resulting CUBE instance uses the default Django development server and therefore is not suitable for production.

### Production deployments

Please refer to https://github.com/FNNDSC/khris-helm

### Development

#### Docker Swarm-based development environment:

Start a local Docker Swarm cluster if not already started:

```bash
docker swarm init --advertise-addr 127.0.0.1
```

Start CUBE from the repository source directory by running the make bash script

```bash
git clone https://github.com/FNNDSC/ChRIS_ultron_backEnd.git
cd ChRIS_ultron_backEnd
./make.sh
```
All the steps performed by the above script are properly documented in the script itself.
After running this script all the automated tests should have successfully run and a Django development server should be running in interactive mode in this terminal.

Later you can stop and remove CUBE services and storage space by running the following bash script from the repository source directory:

```bash
./unmake.sh
```

Then remove the local Docker Swarm cluster if desired:

```bash
docker swarm leave --force
```

#### Kubernetes-based development environment:

Install single-node Kubernetes cluster.
On MAC OS Docker Desktop includes a standalone Kubernetes server and client.
Consult this page https://docs.docker.com/desktop/kubernetes/.
On Linux there is a simple MicroK8s installation. Consult this page https://microk8s.io.
Then create the required alias:

```bash
snap alias microk8s.kubectl kubectl
microk8s.kubectl config view --raw > $HOME/.kube/config
```

Start the Kubernetes cluster:

```bash
microk8s start
```

Start CUBE from the repository source directory by running the make bash script

```bash
git clone https://github.com/FNNDSC/ChRIS_ultron_backEnd.git
cd ChRIS_ultron_backEnd
export HOSTIP=<IP address of this machine>
./make.sh -O kubernetes
```

Later you can stop and remove CUBE services and storage space by running the following bash script from the repository source directory:

```bash
./unmake.sh -O kubernetes
```

Stop the Kubernetes cluster if desired:

```bash
microk8s stop
```

#### Rerun automated tests after modifying source code

Open another terminal and run the Unit and Integration tests within the container running the Django server:

To run only the Unit tests:

```bash
cd ChRIS_ultron_backEnd
docker compose -f docker-compose_dev.yml exec chris_dev python manage.py test --exclude-tag integration
```

To run only the Integration tests:

```bash
docker compose -f docker-compose_dev.yml exec chris_dev python manage.py test --tag integration
```

To run all the tests:

```bash
docker compose -f docker-compose_dev.yml exec chris_dev python manage.py test
```

After running the Integration tests the ``./CHRIS_REMOTE_FS`` directory **must** be empty otherwise it means some error has occurred and you should manually empty it.

#### Check code coverage of the automated tests
Make sure the ``chris_backend/`` dir is world writable. Then type:

```bash
docker compose -f docker-compose_dev.yml exec chris_dev coverage run --source=feeds,plugins,userfiles,users manage.py test
docker compose -f docker-compose_dev.yml exec chris_dev coverage report
```

#### Using [HTTPie](https://httpie.org/) client to play with the REST API
A simple GET request to retrieve the user-specific list of feeds:
```bash
http -a cube:cube1234 http://localhost:8000/api/v1/
```
A simple POST request to run the plugin with id 1:
```bash
http -a cube:cube1234 POST http://localhost:8000/api/v1/plugins/1/instances/ Content-Type:application/vnd.collection+json Accept:application/vnd.collection+json template:='{"data":[{"name":"dir","value":"cube/"}]}'
```
Then keep making the following GET request until the ``"status"`` descriptor in the response becomes ``"finishedSuccessfully"``:
```bash
http -a cube:cube1234 http://localhost:8000/api/v1/plugins/instances/1/
```

#### Using swift client to list files in the users bucket
```bash
swift -A http://127.0.0.1:8080/auth/v1.0 -U chris:chris1234 -K testing list users
```

### Documentation

#### REST API reference

Available [here](https://fnndsc.github.io/ChRIS_ultron_backEnd).

Install Sphinx and the http extension (useful to document the REST API)
```
pip install Sphinx
pip install sphinxcontrib-httpdomain
```

Build the html documentation
```
cd docs/
make html
```

#### ChRIS REST API design.

Available [here](https://github.com/FNNDSC/ChRIS_ultron_backEnd/wiki/ChRIS-REST-API-design).

#### ChRIS backend database design.

Available [here](https://github.com/FNNDSC/ChRIS_ultron_backEnd/wiki/ChRIS-backend-database-design).

#### Wiki.

Available [here](https://github.com/FNNDSC/ChRIS_ultron_backEnd/wiki).

### Learn More

If you are interested in contributing or joining us, Check [here](http://chrisproject.org/join-us).


# Seeder

[![Build Status](https://travis-ci.org/WebArchivCZ/Seeder.svg?branch=master)](https://travis-ci.org/WebArchivCZ/Seeder)
[![Coverage Status](https://coveralls.io/repos/github/WebArchivCZ/Seeder/badge.svg?branch=master)](https://coveralls.io/github/WebArchivCZ/Seeder?branch=master)
[![Documentation Status](https://readthedocs.org/projects/seeder/badge/?version=latest)](https://seeder.readthedocs.org/en/latest/)

Web archivists tool for moderating what parts of Czech Internet will be
archived and what parts should die in the shadows of unarchived wasteland.

Documentation is available at [Read the docs](http://seeder.readthedocs.org/en/latest/).

## Production like environment
Docker compose should work out of box after cloning. Run: ```docker-compose up```. Docker-compose mimics production deployment. So important note is you should ```docker volume rm static``` otherwise static_root volume persists and both nginx and django will not show latest output from collectstatic. Or just run ```./local``` which will always delete nginx and django container and static is corectly deployed.

Check [http://localhost](http://localhost) for Seeder, and [http://localhost:8080](http://localhost:8080) for Traefik.

[Webarchiv.cz deployment instructions](ci/README.md)

## Important branches

- master - development branch
- production - production-ready branch


# Flask

Flask is a lightweight [WSGI][] web application framework. It is designed
to make getting started quick and easy, with the ability to scale up to
complex applications. It began as a simple wrapper around [Werkzeug][]
and [Jinja][], and has become one of the most popular Python web
application frameworks.

Flask offers suggestions, but doesn't enforce any dependencies or
project layout. It is up to the developer to choose the tools and
libraries they want to use. There are many extensions provided by the
community that make adding new functionality easy.

[WSGI]: https://wsgi.readthedocs.io/
[Werkzeug]: https://werkzeug.palletsprojects.com/
[Jinja]: https://jinja.palletsprojects.com/

## A Simple Example

```python
# save this as app.py
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello, World!"
```

```
$ flask run
  * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
```

## Donate

The Pallets organization develops and supports Flask and the libraries
it uses. In order to grow the community of contributors and users, and
allow the maintainers to devote more time to the projects, [please
donate today][].

[please donate today]: https://palletsprojects.com/donate


# Requests

**Requests** is a simple, yet elegant, HTTP library.

```python
>>> import requests
>>> r = requests.get('https://httpbin.org/basic-auth/user/pass', auth=('user', 'pass'))
>>> r.status_code
200
>>> r.headers['content-type']
'application/json; charset=utf8'
>>> r.encoding
'utf-8'
>>> r.text
'{"authenticated": true, ...'
>>> r.json()
{'authenticated': True, ...}
```

Requests allows you to send HTTP/1.1 requests extremely easily. There’s no need to manually add query strings to your URLs, or to form-encode your `PUT` & `POST` data — but nowadays, just use the `json` method!

Requests is one of the most downloaded Python packages today, pulling in around `30M downloads / week`— according to GitHub, Requests is currently [depended upon](https://github.com/psf/requests/network/dependents?package_id=UGFja2FnZS01NzA4OTExNg%3D%3D) by `1,000,000+` repositories. You may certainly put your trust in this code.

[![Downloads](https://static.pepy.tech/badge/requests/month)](https://pepy.tech/project/requests)
[![Supported Versions](https://img.shields.io/pypi/pyversions/requests.svg)](https://pypi.org/project/requests)
[![Contributors](https://img.shields.io/github/contributors/psf/requests.svg)](https://github.com/psf/requests/graphs/contributors)

## Installing Requests and Supported Versions

Requests is available on PyPI:

```console
$ python -m pip install requests
```

Requests officially supports Python 3.8+.

## Supported Features & Best–Practices

Requests is ready for the demands of building robust and reliable HTTP–speaking applications, for the needs of today.

- Keep-Alive & Connection Pooling
- International Domains and URLs
- Sessions with Cookie Persistence
- Browser-style TLS/SSL Verification
- Basic & Digest Authentication
- Familiar `dict`–like Cookies
- Automatic Content Decompression and Decoding
- Multi-part File Uploads
- SOCKS Proxy Support
- Connection Timeouts
- Streaming Downloads
- Automatic honoring of `.netrc`
- Chunked HTTP Requests

## API Reference and User Guide available on [Read the Docs](https://requests.readthedocs.io)

[![Read the Docs](https://raw.githubusercontent.com/psf/requests/main/ext/ss.png)](https://requests.readthedocs.io)

## Cloning the repository

When cloning the Requests repository, you may need to add the `-c
fetch.fsck.badTimezone=ignore` flag to avoid an error about a bad commit (see
[this issue](https://github.com/psf/requests/issues/2690) for more background):

```shell
git clone -c fetch.fsck.badTimezone=ignore https://github.com/psf/requests.git
```

You can also apply this setting to your global Git config:

```shell
git config --global fetch.fsck.badTimezone ignore
```

---

[![Kenneth Reitz](https://raw.githubusercontent.com/psf/requests/main/ext/kr.png)](https://kennethreitz.org) [![Python Software Foundation](https://raw.githubusercontent.com/psf/requests/main/ext/psf.png)](https://www.python.org/psf)


.. image:: https://codecov.io/github/ipython/ipython/coverage.svg?branch=main
    :target: https://codecov.io/github/ipython/ipython?branch=main

.. image:: https://img.shields.io/pypi/v/IPython.svg
    :target: https://pypi.python.org/pypi/ipython

.. image:: https://github.com/ipython/ipython/actions/workflows/test.yml/badge.svg
    :target: https://github.com/ipython/ipython/actions/workflows/test.yml

.. image:: https://www.codetriage.com/ipython/ipython/badges/users.svg
    :target: https://www.codetriage.com/ipython/ipython/

.. image:: https://raster.shields.io/badge/Follows-SPEC--0000-brightgreen.png
    :target: https://scientific-python.org/specs/spec-0000/

.. image:: https://tidelift.com/badges/package/pypi/ipython?style=flat
    :target: https://tidelift.com/subscription/pkg/pypi-ipython

===========================================
 IPython: Productive Interactive Computing
===========================================

Overview
========

Welcome to IPython.  Our full documentation is available on `ipython.readthedocs.io
<https://ipython.readthedocs.io/en/stable/>`_ and contains information on how to install, use, and
contribute to the project.
IPython (Interactive Python) is a command shell for interactive computing in multiple programming languages, originally developed for the Python programming language, that offers introspection, rich media, shell syntax, tab completion, and history.

**IPython versions and Python Support**

Starting after IPython 8.16, we will progressively transition to `Spec-0000 <https://scientific-python.org/specs/spec-0000/>`_.

Starting with IPython 7.10, IPython follows `NEP 29 <https://numpy.org/neps/nep-0029-deprecation_policy.html>`_

**IPython 7.17+** requires Python version 3.7 and above.

**IPython 7.10+** requires Python version 3.6 and above.

**IPython 7.0** requires Python version 3.5 and above.

**IPython 6.x** requires Python version 3.3 and above.

**IPython 5.x LTS** is the compatible release for Python 2.7.
If you require Python 2 support, you **must** use IPython 5.x LTS. Please
update your project configurations and requirements as necessary.

The Notebook, Qt console and a number of other pieces are now parts of *Jupyter*.
See the `Jupyter installation docs <https://jupyter.readthedocs.io/en/latest/install.html>`__
if you want to use these.

Main features of IPython
========================
Comprehensive object introspection.

Input history, persistent across sessions.

Caching of output results during a session with automatically generated references.

Extensible tab completion, with support by default for completion of python variables and keywords, filenames and function keywords.

Extensible system of ‘magic’ commands for controlling the environment and performing many tasks related to IPython or the operating system.

A rich configuration system with easy switching between different setups (simpler than changing $PYTHONSTARTUP environment variables every time).

Session logging and reloading.

Extensible syntax processing for special purpose situations.

Access to the system shell with user-extensible alias system.

Easily embeddable in other Python programs and GUIs.

Integrated access to the pdb debugger and the Python profiler.

Development and Instant running
===============================

You can find the latest version of the development documentation on `readthedocs
<https://ipython.readthedocs.io/en/latest/>`_.

You can run IPython from this directory without even installing it system-wide
by typing at the terminal::

   $ python -m IPython

Or see the `development installation docs
<https://ipython.readthedocs.io/en/latest/install/install.html#installing-the-development-version>`_
for the latest revision on read the docs.

Documentation and installation instructions for older version of IPython can be
found on the `IPython website <https://ipython.org/documentation.html>`_

Alternatives to IPython
=======================

IPython may not be to your taste; if that's the case there might be similar
project that you might want to use:

- The classic Python REPL.
- `bpython <https://bpython-interpreter.org/>`_
- `mypython <https://www.asmeurer.com/mypython/>`_
- `ptpython and ptipython <https://pypi.org/project/ptpython/>`_
- `Xonsh <https://xon.sh/>`_

Ignoring commits with git blame.ignoreRevsFile
==============================================

As of git 2.23, it is possible to make formatting changes without breaking
``git blame``. See the `git documentation
<https://git-scm.com/docs/git-config#Documentation/git-config.txt-blameignoreRevsFile>`_
for more details.

To use this feature you must:

- Install git >= 2.23
- Configure your local git repo by running:
   - POSIX: ``tools\configure-git-blame-ignore-revs.sh``
   - Windows:  ``tools\configure-git-blame-ignore-revs.bat``


.. image:: https://raw.githubusercontent.com/sanic-org/sanic-assets/master/png/sanic-framework-logo-400x97.png
    :alt: Sanic | Build fast. Run fast.

Sanic | Build fast. Run fast.
=============================

.. start-badges

.. list-table::
    :widths: 15 85
    :stub-columns: 1

    * - Build
      - | |Tests|
    * - Docs
      - | |UserGuide| |Documentation|
    * - Package
      - | |PyPI| |PyPI version| |Wheel| |Supported implementations| |Code style ruff|
    * - Support
      - | |Forums| |Discord| |Awesome|
    * - Stats
      - | |Monthly Downloads| |Weekly Downloads| |Conda downloads|

.. |UserGuide| image:: https://img.shields.io/badge/user%20guide-sanic-ff0068
   :target: https://sanic.dev/
.. |Forums| image:: https://img.shields.io/badge/forums-community-ff0068.svg
   :target: https://community.sanicframework.org/
.. |Discord| image:: https://img.shields.io/discord/812221182594121728?logo=discord&label=Discord&color=5865F2
   :target: https://discord.gg/FARQzAEMAA
.. |Tests| image:: https://github.com/sanic-org/sanic/actions/workflows/tests.yml/badge.svg?branch=main
   :target: https://github.com/sanic-org/sanic/actions/workflows/tests.yml
.. |Documentation| image:: https://readthedocs.org/projects/sanic/badge/?version=latest
   :target: http://sanic.readthedocs.io/en/latest/?badge=latest
.. |PyPI| image:: https://img.shields.io/pypi/v/sanic.svg
   :target: https://pypi.python.org/pypi/sanic/
.. |PyPI version| image:: https://img.shields.io/pypi/pyversions/sanic.svg
   :target: https://pypi.python.org/pypi/sanic/
.. |Code style ruff| image:: https://img.shields.io/badge/code%20style-ruff-000000.svg
    :target: https://docs.astral.sh/ruff/
.. |Wheel| image:: https://img.shields.io/pypi/wheel/sanic.svg
    :alt: PyPI Wheel
    :target: https://pypi.python.org/pypi/sanic
.. |Supported implementations| image:: https://img.shields.io/pypi/implementation/sanic.svg
    :alt: Supported implementations
    :target: https://pypi.python.org/pypi/sanic
.. |Awesome| image:: https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg
    :alt: Awesome Sanic List
    :target: https://github.com/mekicha/awesome-sanic
.. |Monthly Downloads| image:: https://img.shields.io/pypi/dm/sanic.svg
    :alt: Downloads
    :target: https://pepy.tech/project/sanic
.. |Weekly Downloads| image:: https://img.shields.io/pypi/dw/sanic.svg
    :alt: Downloads
    :target: https://pepy.tech/project/sanic
.. |Conda downloads| image:: https://img.shields.io/conda/dn/conda-forge/sanic.svg
    :alt: Downloads
    :target: https://anaconda.org/conda-forge/sanic

.. end-badges

Sanic is a **Python 3.8+** web server and web framework that's written to go fast. It allows the usage of the ``async/await`` syntax added in Python 3.5, which makes your code non-blocking and speedy.

Sanic is also ASGI compliant, so you can deploy it with an `alternative ASGI webserver <https://sanicframework.org/en/guide/deployment/running.html#asgi>`_.

`Source code on GitHub <https://github.com/sanic-org/sanic/>`_ | `Help and discussion board <https://community.sanicframework.org/>`_ | `User Guide <https://sanicframework.org>`_ | `Chat on Discord <https://discord.gg/FARQzAEMAA>`_

The project is maintained by the community, for the community. **Contributions are welcome!**

The goal of the project is to provide a simple way to get up and running a highly performant HTTP server that is easy to build, to expand, and ultimately to scale.

Sponsor
-------

Check out `open collective <https://opencollective.com/sanic-org>`_ to learn more about helping to fund Sanic.

Installation
------------

``pip3 install sanic``

    Sanic makes use of ``uvloop`` and ``ujson`` to help with performance. If you do not want to use those packages, simply add an environmental variable ``SANIC_NO_UVLOOP=true`` or ``SANIC_NO_UJSON=true`` at install time.

    .. code:: shell

       $ export SANIC_NO_UVLOOP=true
       $ export SANIC_NO_UJSON=true
       $ pip3 install --no-binary :all: sanic

.. note::

  If you are running on a clean install of Fedora 28 or above, please make sure you have the ``redhat-rpm-config`` package installed in case if you want to
  use ``sanic`` with ``ujson`` dependency.

Hello World Example
-------------------

.. code:: python

    from sanic import Sanic
    from sanic.response import json

    app = Sanic("my-hello-world-app")

    @app.route('/')
    async def test(request):
        return json({'hello': 'world'})

    if __name__ == '__main__':
        app.run()

Sanic can now be easily run using ``sanic hello.app``.

.. code::

    [2018-12-30 11:37:41 +0200] [13564] [INFO] Goin' Fast @ http://127.0.0.1:8000
    [2018-12-30 11:37:41 +0200] [13564] [INFO] Starting worker [13564]

And, we can verify it is working: ``curl localhost:8000 -i``

.. code::

    HTTP/1.1 200 OK
    Connection: keep-alive
    Keep-Alive: 5
    Content-Length: 17
    Content-Type: application/json

    {"hello":"world"}

**Now, let's go build something fast!**

Minimum Python version is 3.8. If you need Python 3.7 support, please use v22.12LTS.

Documentation
-------------

User Guide, Changelog, and API Documentation can be found at `sanic.dev <https://sanic.dev>`__.

Questions and Discussion
------------------------

`Ask a question or join the conversation <https://community.sanicframework.org/>`__.

Contribution
------------

We are always happy to have new contributions. We have `marked issues good for anyone looking to get started <https://github.com/sanic-org/sanic/issues?q=is%3Aopen+is%3Aissue+label%3Abeginner>`_, and welcome `questions on the forums <https://community.sanicframework.org/>`_. Please take a look at our `Contribution guidelines <https://github.com/sanic-org/sanic/blob/master/CONTRIBUTING.rst>`_.


# Jinja

Jinja is a fast, expressive, extensible templating engine. Special
placeholders in the template allow writing code similar to Python
syntax. Then the template is passed data to render the final document.

It includes:

-   Template inheritance and inclusion.
-   Define and import macros within templates.
-   HTML templates can use autoescaping to prevent XSS from untrusted
    user input.
-   A sandboxed environment can safely render untrusted templates.
-   AsyncIO support for generating templates and calling async
    functions.
-   I18N support with Babel.
-   Templates are compiled to optimized Python code just-in-time and
    cached, or can be compiled ahead-of-time.
-   Exceptions point to the correct line in templates to make debugging
    easier.
-   Extensible filters, tests, functions, and even syntax.

Jinja's philosophy is that while application logic belongs in Python if
possible, it shouldn't make the template designer's job difficult by
restricting functionality too much.

## In A Nutshell

```jinja
{% extends "base.html" %}
{% block title %}Members{% endblock %}
{% block content %}
  <ul>
  {% for user in users %}
    <li><a href="{{ user.url }}">{{ user.username }}</a></li>
  {% endfor %}
  </ul>
{% endblock %}
```

## Donate

The Pallets organization develops and supports Jinja and other popular
packages. In order to grow the community of contributors and users, and
allow the maintainers to devote more time to the projects, [please
donate today][].

[please donate today]: https://palletsprojects.com/donate


Django Channels
===============

.. image:: https://github.com/django/channels/workflows/Tests/badge.svg?branch=master
    :target: https://github.com/django/channels/actions

.. image:: https://readthedocs.org/projects/channels/badge/?version=latest
    :target: https://channels.readthedocs.io/en/latest/?badge=latest

.. image:: https://img.shields.io/pypi/v/channels.svg
    :target: https://pypi.python.org/pypi/channels

.. image:: https://img.shields.io/pypi/l/channels.svg
    :target: https://pypi.python.org/pypi/channels

Channels augments Django to bring WebSocket, long-poll HTTP,
task offloading and other async support to your code, using familiar Django
design patterns and a flexible underlying framework that lets you not only
customize behaviours but also write support for your own protocols and needs.

Documentation, installation and getting started instructions are at
https://channels.readthedocs.io

Channels is an official Django Project and as such has a deprecation policy.
Details about what's deprecated or pending deprecation for each release is in
the `release notes <https://channels.readthedocs.io/en/latest/releases/index.html>`_.

Support can be obtained through several locations - see our
`support docs <https://channels.readthedocs.io/en/latest/support.html>`_ for more.

You can install channels from PyPI as the ``channels`` package.
See our `installation <https://channels.readthedocs.io/en/latest/installation.html>`_
and `tutorial <https://channels.readthedocs.io/en/latest/tutorial/index.html>`_ docs for more.

Dependencies
------------

All Channels projects currently support Python 3.8 and up. ``channels`` is
compatible with Django 4.2 and 5.0.

Contributing
------------

To learn more about contributing, please `read our contributing docs <https://channels.readthedocs.io/en/latest/contributing.html>`_.

Maintenance and Security
------------------------

To report security issues, please contact security@djangoproject.com. For GPG
signatures and more security process information, see
https://docs.djangoproject.com/en/dev/internals/security/.

To report bugs or request new features, please open a new GitHub issue. For
larger discussions, please post to the
`django-developers mailing list <https://groups.google.com/d/forum/django-developers>`_.

Maintenance is overseen by Carlton Gibson with help from others. It is a
best-effort basis - we unfortunately can only dedicate guaranteed time to fixing
security holes.

If you are interested in joining the maintenance team, please
`read more about contributing <https://channels.readthedocs.io/en/latest/contributing.html>`_
and get in touch!

Other Projects
--------------

The Channels project is made up of several packages; the others are:

* `Daphne <https://github.com/django/daphne/>`_, the HTTP and Websocket termination server
* `channels_redis <https://github.com/django/channels_redis/>`_, the Redis channel backend
* `asgiref <https://github.com/django/asgiref/>`_, the base ASGI library/memory backend


[![jazzband-image]][jazzband]
[![pypi][pypi-image]][pypi]
[![pyversions][pyversions-image]][pyversions]
[![pre-commit][pre-commit-image]][pre-commit]
[![buildstatus-gha][buildstatus-gha-image]][buildstatus-gha]
[![codecov][codecov-image]][codecov]
[![Matrix Room Badge]][Matrix Room]
[![Matrix Space Badge]][Matrix Space]
[![discord-chat-image]][discord-chat]

# pip-tools = pip-compile + pip-sync

A set of command line tools to help you keep your `pip`-based packages fresh,
even when you've pinned them. You do pin them, right? (In building your Python application and its dependencies for production, you want to make sure that your builds are predictable and deterministic.)

[![pip-tools overview for phase II][pip-tools-overview]][pip-tools-overview]

## Installation

Similar to `pip`, `pip-tools` must be installed in each of your project's
[virtual environments](https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments):

```console
$ source /path/to/venv/bin/activate
(venv) $ python -m pip install pip-tools
```

**Note**: all of the remaining example commands assume you've activated your
project's virtual environment.

## Example usage for `pip-compile`

The `pip-compile` command lets you compile a `requirements.txt` file from
your dependencies, specified in either `pyproject.toml`, `setup.cfg`,
`setup.py`, or `requirements.in`.

Run it with `pip-compile` or `python -m piptools compile` (or
`pipx run --spec pip-tools pip-compile` if `pipx` was installed with the
appropriate Python version). If you use multiple Python versions, you can also
run `py -X.Y -m piptools compile` on Windows and `pythonX.Y -m piptools compile`
on other systems.

`pip-compile` should be run from the same virtual environment as your
project so conditional dependencies that require a specific Python version,
or other environment markers, resolve relative to your project's
environment.

**Note**: If `pip-compile` finds an existing `requirements.txt` file that
fulfils the dependencies then no changes will be made, even if updates are
available. To compile from scratch, first delete the existing
`requirements.txt` file, or see
[Updating requirements](#updating-requirements)
for alternative approaches.

### Requirements from `pyproject.toml`

The `pyproject.toml` file is the
[latest standard](https://peps.python.org/pep-0621/) for configuring
packages and applications, and is recommended for new projects. `pip-compile`
supports both installing your `project.dependencies` as well as your
`project.optional-dependencies`. Thanks to the fact that this is an
official standard, you can use `pip-compile` to pin the dependencies
in projects that use modern standards-adhering packaging tools like
[Setuptools](https://setuptools.pypa.io), [Hatch](https://hatch.pypa.io/)
or [flit](https://flit.pypa.io/).

Suppose you have a 'foobar' Python application that is packaged using `Setuptools`,
and you want to pin it for production. You can declare the project metadata as:

```toml
[build-system]
requires = ["setuptools", "setuptools-scm"]
build-backend = "setuptools.build_meta"

[project]
requires-python = ">=3.9"
name = "foobar"
dynamic = ["dependencies", "optional-dependencies"]

[tool.setuptools.dynamic]
dependencies = { file = ["requirements.in"] }
optional-dependencies.test = { file = ["requirements-test.txt"] }

```

If you have a Django application that is packaged using `Hatch`, and you
want to pin it for production. You also want to pin your development tools
in a separate pin file. You declare `django` as a dependency and create an
optional dependency `dev` that includes `pytest`:

```toml
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "my-cool-django-app"
version = "42"
dependencies = ["django"]

[project.optional-dependencies]
dev = ["pytest"]
```

You can produce your pin files as easily as:

```console
$ pip-compile -o requirements.txt pyproject.toml
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
#    pip-compile --output-file=requirements.txt pyproject.toml
#
asgiref==3.6.0
    # via django
django==4.1.7
    # via my-cool-django-app (pyproject.toml)
sqlparse==0.4.3
    # via django

$ pip-compile --extra dev -o dev-requirements.txt pyproject.toml
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
#    pip-compile --extra=dev --output-file=dev-requirements.txt pyproject.toml
#
asgiref==3.6.0
    # via django
attrs==22.2.0
    # via pytest
django==4.1.7
    # via my-cool-django-app (pyproject.toml)
exceptiongroup==1.1.1
    # via pytest
iniconfig==2.0.0
    # via pytest
packaging==23.0
    # via pytest
pluggy==1.0.0
    # via pytest
pytest==7.2.2
    # via my-cool-django-app (pyproject.toml)
sqlparse==0.4.3
    # via django
tomli==2.0.1
    # via pytest
```

This is great for both pinning your applications, but also to keep the CI
of your open-source Python package stable.

### Requirements from `setup.py` and `setup.cfg`

`pip-compile` has also full support for `setup.py`- and
`setup.cfg`-based projects that use `setuptools`.

Just define your dependencies and extras as usual and run
`pip-compile` as above.

### Requirements from `requirements.in`

You can also use plain text files for your requirements (e.g. if you don't
want your application to be a package). To use a `requirements.in` file to
declare the Django dependency:

```
# requirements.in
django
```

Now, run `pip-compile requirements.in`:

```console
$ pip-compile requirements.in
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
#    pip-compile requirements.in
#
asgiref==3.6.0
    # via django
django==4.1.7
    # via -r requirements.in
sqlparse==0.4.3
    # via django
```

And it will produce your `requirements.txt`, with all the Django dependencies
(and all underlying dependencies) pinned.

(updating-requirements)=

### Updating requirements

`pip-compile` generates a `requirements.txt` file using the latest versions
that fulfil the dependencies you specify in the supported files.

If `pip-compile` finds an existing `requirements.txt` file that fulfils the
dependencies then no changes will be made, even if updates are available.

To force `pip-compile` to update all packages in an existing
`requirements.txt`, run `pip-compile --upgrade`.

To update a specific package to the latest or a specific version use the
`--upgrade-package` or `-P` flag:

```console
# only update the django package
$ pip-compile --upgrade-package django

# update both the django and requests packages
$ pip-compile --upgrade-package django --upgrade-package requests

# update the django package to the latest, and requests to v2.0.0
$ pip-compile --upgrade-package django --upgrade-package requests==2.0.0
```

You can combine `--upgrade` and `--upgrade-package` in one command, to
provide constraints on the allowed upgrades. For example to upgrade all
packages whilst constraining requests to the latest version less than 3.0:

```console
$ pip-compile --upgrade --upgrade-package 'requests<3.0'
```

### Using hashes

If you would like to use _Hash-Checking Mode_ available in `pip` since
version 8.0, `pip-compile` offers `--generate-hashes` flag:

```console
$ pip-compile --generate-hashes requirements.in
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
#    pip-compile --generate-hashes requirements.in
#
asgiref==3.6.0 \
    --hash=sha256:71e68008da809b957b7ee4b43dbccff33d1b23519fb8344e33f049897077afac \
    --hash=sha256:9567dfe7bd8d3c8c892227827c41cce860b368104c3431da67a0c5a65a949506
    # via django
django==4.1.7 \
    --hash=sha256:44f714b81c5f190d9d2ddad01a532fe502fa01c4cb8faf1d081f4264ed15dcd8 \
    --hash=sha256:f2f431e75adc40039ace496ad3b9f17227022e8b11566f4b363da44c7e44761e
    # via -r requirements.in
sqlparse==0.4.3 \
    --hash=sha256:0323c0ec29cd52bceabc1b4d9d579e311f3e4961b98d174201d5622a23b85e34 \
    --hash=sha256:69ca804846bb114d2ec380e4360a8a340db83f0ccf3afceeb1404df028f57268
    # via django
```

### Output File

To output the pinned requirements in a filename other than
`requirements.txt`, use `--output-file`. This might be useful for compiling
multiple files, for example with different constraints on django to test a
library with both versions using [tox](https://tox.readthedocs.io/en/latest/):

```console
$ pip-compile --upgrade-package 'django<1.0' --output-file requirements-django0x.txt
$ pip-compile --upgrade-package 'django<2.0' --output-file requirements-django1x.txt
```

Or to output to standard output, use `--output-file=-`:

```console
$ pip-compile --output-file=- > requirements.txt
$ pip-compile - --output-file=- < requirements.in > requirements.txt
```

### Forwarding options to `pip`

Any valid `pip` flags or arguments may be passed on with `pip-compile`'s
`--pip-args` option, e.g.

```console
$ pip-compile requirements.in --pip-args "--retries 10 --timeout 30"
```

### Configuration

You can define project-level defaults for `pip-compile` and `pip-sync` by
writing them to a configuration file in the same directory as your requirements
input files (or the current working directory if piping input from stdin).
By default, both `pip-compile` and `pip-sync` will look first
for a `.pip-tools.toml` file and then in your `pyproject.toml`. You can
also specify an alternate TOML configuration file with the `--config` option.

It is possible to specify configuration values both globally and command-specific.
For example, to by default generate `pip` hashes in the resulting
requirements file output, you can specify in a configuration file:

```toml
[tool.pip-tools]
generate-hashes = true
```

Options to `pip-compile` and `pip-sync` that may be used more than once
must be defined as lists in a configuration file, even if they only have one
value.

`pip-tools` supports default values for [all valid command-line flags](/cli/index.md)
of its subcommands. Configuration keys may contain underscores instead of dashes,
so the above could also be specified in this format:

```toml
[tool.pip-tools]
generate_hashes = true
```

Configuration defaults specific to `pip-compile` and `pip-sync` can be put beneath
separate sections. For example, to by default perform a dry-run with `pip-compile`:

```toml
[tool.pip-tools.compile] # "sync" for pip-sync
dry-run = true
```

This does not affect the `pip-sync` command, which also has a `--dry-run` option.
Note that local settings take preference over the global ones of the same name,
whenever both are declared, thus this would also make `pip-compile` generate hashes,
but discard the global dry-run setting:

```toml
[tool.pip-tools]
generate-hashes = true
dry-run = true

[tool.pip-tools.compile]
dry-run = false
```

You might be wrapping the `pip-compile` command in another script. To avoid
confusing consumers of your custom script you can override the update command
generated at the top of requirements files by setting the
`CUSTOM_COMPILE_COMMAND` environment variable.

```console
$ CUSTOM_COMPILE_COMMAND="./pipcompilewrapper" pip-compile requirements.in
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
#    ./pipcompilewrapper
#
asgiref==3.6.0
    # via django
django==4.1.7
    # via -r requirements.in
sqlparse==0.4.3
    # via django
```

### Workflow for layered requirements

If you have different environments that you need to install different but
compatible packages for, then you can create layered requirements files and use
one layer to constrain the other.

For example, if you have a Django project where you want the newest `2.1`
release in production and when developing you want to use the Django debug
toolbar, then you can create two `*.in` files, one for each layer:

```
# requirements.in
django<2.2
```

At the top of the development requirements `dev-requirements.in` you use `-c
requirements.txt` to constrain the dev requirements to packages already
selected for production in `requirements.txt`.

```
# dev-requirements.in
-c requirements.txt
django-debug-toolbar<2.2
```

First, compile `requirements.txt` as usual:

```
$ pip-compile
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
#    pip-compile
#
django==2.1.15
    # via -r requirements.in
pytz==2023.3
    # via django
```

Now compile the dev requirements and the `requirements.txt` file is used as
a constraint:

```console
$ pip-compile dev-requirements.in
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
#    pip-compile dev-requirements.in
#
django==2.1.15
    # via
    #   -c requirements.txt
    #   django-debug-toolbar
django-debug-toolbar==2.1
    # via -r dev-requirements.in
pytz==2023.3
    # via
    #   -c requirements.txt
    #   django
sqlparse==0.4.3
    # via django-debug-toolbar
```

As you can see above, even though a `2.2` release of Django is available, the
dev requirements only include a `2.1` version of Django because they were
constrained. Now both compiled requirements files can be installed safely in
the dev environment.

To install requirements in production stage use:

```console
$ pip-sync
```

You can install requirements in development stage by:

```console
$ pip-sync requirements.txt dev-requirements.txt
```

### Version control integration

You might use `pip-compile` as a hook for the [pre-commit](https://github.com/pre-commit/pre-commit).
See [pre-commit docs](https://pre-commit.com/) for instructions.
Sample `.pre-commit-config.yaml`:

```yaml
repos:
  - repo: https://github.com/jazzband/pip-tools
    rev: 7.4.1
    hooks:
      - id: pip-compile
```

You might want to customize `pip-compile` args by configuring `args` and/or `files`, for example:

```yaml
repos:
  - repo: https://github.com/jazzband/pip-tools
    rev: 7.4.1
    hooks:
      - id: pip-compile
        files: ^requirements/production\.(in|txt)$
        args: [--index-url=https://example.com, requirements/production.in]
```

If you have multiple requirement files make sure you create a hook for each file.

```yaml
repos:
  - repo: https://github.com/jazzband/pip-tools
    rev: 7.4.1
    hooks:
      - id: pip-compile
        name: pip-compile setup.py
        files: ^(setup\.py|requirements\.txt)$
      - id: pip-compile
        name: pip-compile requirements-dev.in
        args: [requirements-dev.in]
        files: ^requirements-dev\.(in|txt)$
      - id: pip-compile
        name: pip-compile requirements-lint.in
        args: [requirements-lint.in]
        files: ^requirements-lint\.(in|txt)$
      - id: pip-compile
        name: pip-compile requirements.in
        args: [requirements.in]
        files: ^requirements\.(in|txt)$
```

### Example usage for `pip-sync`

Now that you have a `requirements.txt`, you can use `pip-sync` to update
your virtual environment to reflect exactly what's in there. This will
install/upgrade/uninstall everything necessary to match the
`requirements.txt` contents.

Run it with `pip-sync` or `python -m piptools sync`. If you use multiple
Python versions, you can also run `py -X.Y -m piptools sync` on Windows and
`pythonX.Y -m piptools sync` on other systems.

`pip-sync` must be installed into and run from the same virtual
environment as your project to identify which packages to install
or upgrade.

**Be careful**: `pip-sync` is meant to be used only with a
`requirements.txt` generated by `pip-compile`.

```console
$ pip-sync
Uninstalling flake8-2.4.1:
    Successfully uninstalled flake8-2.4.1
Collecting click==4.1
    Downloading click-4.1-py2.py3-none-any.whl (62kB)
    100% |................................| 65kB 1.8MB/s
    Found existing installation: click 4.0
    Uninstalling click-4.0:
        Successfully uninstalled click-4.0
Successfully installed click-4.1
```

To sync multiple `*.txt` dependency lists, just pass them in via command
line arguments, e.g.

```console
$ pip-sync dev-requirements.txt requirements.txt
```

Passing in empty arguments would cause it to default to `requirements.txt`.

Any valid `pip install` flags or arguments may be passed with `pip-sync`'s
`--pip-args` option, e.g.

```console
$ pip-sync requirements.txt --pip-args "--no-cache-dir --no-deps"
```

**Note**: `pip-sync` will not upgrade or uninstall packaging tools like
`setuptools`, `pip`, or `pip-tools` itself. Use `python -m pip install --upgrade`
to upgrade those packages.

### Should I commit `requirements.in` and `requirements.txt` to source control?

Generally, yes. If you want a reproducible environment installation available from your source control,
then yes, you should commit both `requirements.in` and `requirements.txt` to source control.

Note that if you are deploying on multiple Python environments (read the section below),
then you must commit a separate output file for each Python environment.
We suggest to use the `{env}-requirements.txt` format
(ex: `win32-py3.7-requirements.txt`, `macos-py3.10-requirements.txt`, etc.).

### Cross-environment usage of `requirements.in`/`requirements.txt` and `pip-compile`

The dependencies of a package can change depending on the Python environment in which it
is installed. Here, we define a Python environment as the combination of Operating
System, Python version (3.7, 3.8, etc.), and Python implementation (CPython, PyPy,
etc.). For an exact definition, refer to the possible combinations of [PEP 508
environment markers][environment-markers].

As the resulting `requirements.txt` can differ for each environment, users must
execute `pip-compile` **on each Python environment separately** to generate a
`requirements.txt` valid for each said environment. The same `requirements.in` can
be used as the source file for all environments, using
[PEP 508 environment markers][environment-markers] as
needed, the same way it would be done for regular `pip` cross-environment usage.

If the generated `requirements.txt` remains exactly the same for all Python
environments, then it can be used across Python environments safely. **But** users
should be careful as any package update can introduce environment-dependent
dependencies, making any newly generated `requirements.txt` environment-dependent too.
As a general rule, it's advised that users should still always execute `pip-compile`
on each targeted Python environment to avoid issues.

### Maximizing reproducibility

`pip-tools` is a great tool to improve the reproducibility of builds.
But there are a few things to keep in mind.

- `pip-compile` will produce different results in different environments as described in the previous section.
- `pip` must be used with the `PIP_CONSTRAINT` environment variable to lock dependencies in build environments as documented in [#8439](https://github.com/pypa/pip/issues/8439).
- Dependencies come from many sources.

Continuing the `pyproject.toml` example from earlier, creating a single lock file could be done like:

```console
$ pip-compile --all-build-deps --all-extras --output-file=constraints.txt --strip-extras pyproject.toml
#
# This file is autogenerated by pip-compile with Python 3.9
# by the following command:
#
#    pip-compile --all-build-deps --all-extras --output-file=constraints.txt --strip-extras pyproject.toml
#
asgiref==3.5.2
    # via django
attrs==22.1.0
    # via pytest
backports-zoneinfo==0.2.1
    # via django
django==4.1
    # via my-cool-django-app (pyproject.toml)
editables==0.3
    # via hatchling
hatchling==1.11.1
    # via my-cool-django-app (pyproject.toml::build-system.requires)
iniconfig==1.1.1
    # via pytest
packaging==21.3
    # via
    #   hatchling
    #   pytest
pathspec==0.10.2
    # via hatchling
pluggy==1.0.0
    # via
    #   hatchling
    #   pytest
py==1.11.0
    # via pytest
pyparsing==3.0.9
    # via packaging
pytest==7.1.2
    # via my-cool-django-app (pyproject.toml)
sqlparse==0.4.2
    # via django
tomli==2.0.1
    # via
    #   hatchling
    #   pytest
```

Some build backends may also request build dependencies dynamically using the `get_requires_for_build_` hooks described in [PEP 517] and [PEP 660].
This will be indicated in the output with one of the following suffixes:

- `(pyproject.toml::build-system.backend::editable)`
- `(pyproject.toml::build-system.backend::sdist)`
- `(pyproject.toml::build-system.backend::wheel)`

### Other useful tools

- [pip-compile-multi](https://pip-compile-multi.readthedocs.io/en/latest/) - pip-compile command wrapper for multiple cross-referencing requirements files.
- [pipdeptree](https://github.com/tox-dev/pipdeptree) to print the dependency tree of the installed packages.
- `requirements.in`/`requirements.txt` syntax highlighting:

  - [requirements.txt.vim](https://github.com/raimon49/requirements.txt.vim) for Vim.
  - [Python extension for VS Code](https://marketplace.visualstudio.com/items?itemName=ms-python.python) for VS Code.
  - [pip-requirements.el](https://github.com/Wilfred/pip-requirements.el) for Emacs.

### Deprecations

This section lists `pip-tools` features that are currently deprecated.

- In the next major release, the `--allow-unsafe` behavior will be enabled by
  default (https://github.com/jazzband/pip-tools/issues/989).
  Use `--no-allow-unsafe` to keep the old behavior. It is recommended
  to pass `--allow-unsafe` now to adapt to the upcoming change.
- The legacy resolver is deprecated and will be removed in future versions.
  The new default is `--resolver=backtracking`.
- In the next major release, the `--strip-extras` behavior will be enabled by
  default (https://github.com/jazzband/pip-tools/issues/1613).
  Use `--no-strip-extras` to keep the old behavior.

### A Note on Resolvers

You can choose from either default backtracking resolver or the deprecated legacy resolver.

The legacy resolver will occasionally fail to resolve dependencies. The
backtracking resolver is more robust, but can take longer to run in general.

You can continue using the legacy resolver with `--resolver=legacy` although
note that it is deprecated and will be removed in a future release.

[jazzband]: https://jazzband.co/
[jazzband-image]: https://jazzband.co/static/img/badge.svg
[pypi]: https://pypi.org/project/pip-tools/
[pypi-image]: https://img.shields.io/pypi/v/pip-tools.svg
[pyversions]: https://pypi.org/project/pip-tools/
[pyversions-image]: https://img.shields.io/pypi/pyversions/pip-tools.svg
[pre-commit]: https://results.pre-commit.ci/latest/github/jazzband/pip-tools/main
[pre-commit-image]: https://results.pre-commit.ci/badge/github/jazzband/pip-tools/main.svg
[buildstatus-gha]: https://github.com/jazzband/pip-tools/actions?query=workflow%3ACI
[buildstatus-gha-image]: https://github.com/jazzband/pip-tools/workflows/CI/badge.svg
[codecov]: https://codecov.io/gh/jazzband/pip-tools
[codecov-image]: https://codecov.io/gh/jazzband/pip-tools/branch/main/graph/badge.svg
[Matrix Room Badge]: https://img.shields.io/matrix/pip-tools:matrix.org?label=Discuss%20on%20Matrix%20at%20%23pip-tools%3Amatrix.org&logo=matrix&server_fqdn=matrix.org&style=flat
[Matrix Room]: https://matrix.to/#/%23pip-tools:matrix.org
[Matrix Space Badge]: https://img.shields.io/matrix/jazzband:matrix.org?label=Discuss%20on%20Matrix%20at%20%23jazzband%3Amatrix.org&logo=matrix&server_fqdn=matrix.org&style=flat
[Matrix Space]: https://matrix.to/#/%23jazzband:matrix.org
[pip-tools-overview]: https://github.com/jazzband/pip-tools/raw/main/img/pip-tools-overview.svg
[environment-markers]: https://peps.python.org/pep-0508/#environment-markers
[PEP 517]: https://peps.python.org/pep-0517/
[PEP 660]: https://peps.python.org/pep-0660/
[discord-chat]: https://discord.gg/pypa
[discord-chat-image]: https://img.shields.io/discord/803025117553754132?label=Discord%20chat%20%23pip-tools&style=flat-square