# AWS SDK for pandas (awswrangler)

*Pandas on AWS*

Easy integration with Athena, Glue, Redshift, Timestream, OpenSearch, Neptune, QuickSight, Chime, CloudWatchLogs, DynamoDB, EMR, SecretManager, PostgreSQL, MySQL, SQLServer and S3 (Parquet, CSV, JSON and EXCEL).

![AWS SDK for pandas](https://github.com/aws/aws-sdk-pandas/blob/main/docs/source/_static/logo2.png?raw=true "AWS SDK for pandas")
![tracker](https://d3tiqpr4kkkomd.cloudfront.net/img/pixel.png?asset=GVOYN2BOOQ573LTVIHEW)

> An [AWS Professional Service](https://aws.amazon.com/professional-services/) open source initiative | aws-proserve-opensource@amazon.com

[![PyPi](https://img.shields.io/pypi/v/awswrangler)](https://pypi.org/project/awswrangler/)
[![Conda](https://img.shields.io/conda/vn/conda-forge/awswrangler)](https://anaconda.org/conda-forge/awswrangler)
[![Python Version](https://img.shields.io/pypi/pyversions/awswrangler.svg)](https://pypi.org/project/awswrangler/)
[![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

[![Checked with mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/)
![Static Checking](https://github.com/aws/aws-sdk-pandas/workflows/Static%20Checking/badge.svg?branch=main)
[![Documentation Status](https://readthedocs.org/projects/aws-sdk-pandas/badge/?version=latest)](https://aws-sdk-pandas.readthedocs.io/?badge=latest)

| Source | Downloads | Installation Command |
|--------|-----------|----------------------|
| **[PyPi](https://pypi.org/project/awswrangler/)**  | [![PyPI Downloads](https://img.shields.io/pypi/dm/awswrangler)](https://pypi.org/project/awswrangler/) | `pip install awswrangler` |
| **[Conda](https://anaconda.org/conda-forge/awswrangler)** | [![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/awswrangler.svg)](https://anaconda.org/conda-forge/awswrangler) | `conda install -c conda-forge awswrangler` |

> ⚠ **Starting version 3.0, optional modules must be installed explicitly:**

➡`pip install 'awswrangler[redshift]'`

## Table of contents

- [Quick Start](#quick-start)
- [At Scale](#at-scale)
- [Read The Docs](#read-the-docs)
- [Getting Help](#getting-help)
- [Logging](#logging)

## Quick Start

Installation command: `pip install awswrangler`

> ⚠ **Starting version 3.0, optional modules must be installed explicitly:**

➡`pip install 'awswrangler[redshift]'`

```py3
import awswrangler as wr
import pandas as pd
from datetime import datetime

df = pd.DataFrame({"id": [1, 2], "value": ["foo", "boo"]})

# Storing data on Data Lake
wr.s3.to_parquet(
    df=df,
    path="s3://bucket/dataset/",
    dataset=True,
    database="my_db",
    table="my_table"
)

# Retrieving the data directly from Amazon S3
df = wr.s3.read_parquet("s3://bucket/dataset/", dataset=True)

# Retrieving the data from Amazon Athena
df = wr.athena.read_sql_query("SELECT * FROM my_table", database="my_db")

# Get a Redshift connection from Glue Catalog and retrieving data from Redshift Spectrum
con = wr.redshift.connect("my-glue-connection")
df = wr.redshift.read_sql_query("SELECT * FROM external_schema.my_table", con=con)
con.close()

# Amazon Timestream Write
df = pd.DataFrame({
    "time": [datetime.now(), datetime.now()],
    "my_dimension": ["foo", "boo"],
    "measure": [1.0, 1.1],
})
rejected_records = wr.timestream.write(df,
    database="sampleDB",
    table="sampleTable",
    time_col="time",
    measure_col="measure",
    dimensions_cols=["my_dimension"],
)

# Amazon Timestream Query
wr.timestream.query("""
SELECT time, measure_value::double, my_dimension
FROM "sampleDB"."sampleTable" ORDER BY time DESC LIMIT 3
""")

```

## At scale
AWS SDK for pandas can also run your workflows at scale by leveraging [Modin](https://modin.readthedocs.io/en/stable/) and [Ray](https://www.ray.io/). Both projects aim to speed up data workloads by distributing processing over a cluster of workers.

Read our [docs](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/scale.html) or head to our latest [tutorials](https://github.com/aws/aws-sdk-pandas/tree/main/tutorials) to learn more.

> ⚠ **Ray is currently not available for Python 3.12. While AWS SDK for pandas supports Python 3.12, it cannot be used at scale.**

## [Read The Docs](https://aws-sdk-pandas.readthedocs.io/)

- [**What is AWS SDK for pandas?**](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/about.html)
- [**Install**](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/install.html)
  - [PyPi (pip)](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/install.html#pypi-pip)
  - [Conda](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/install.html#conda)
  - [AWS Lambda Layer](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/install.html#aws-lambda-layer)
  - [AWS Glue Python Shell Jobs](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/install.html#aws-glue-python-shell-jobs)
  - [AWS Glue PySpark Jobs](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/install.html#aws-glue-pyspark-jobs)
  - [Amazon SageMaker Notebook](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/install.html#amazon-sagemaker-notebook)
  - [Amazon SageMaker Notebook Lifecycle](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/install.html#amazon-sagemaker-notebook-lifecycle)
  - [EMR](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/install.html#emr)
  - [From source](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/install.html#from-source)
- [**At scale**](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/scale.html)
  - [Getting Started](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/scale.html#getting-started)
  - [Supported APIs](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/scale.html#supported-apis)
  - [Resources](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/scale.html#resources)
- [**Tutorials**](https://github.com/aws/aws-sdk-pandas/tree/main/tutorials)
  - [001 - Introduction](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/001%20-%20Introduction.ipynb)
  - [002 - Sessions](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/002%20-%20Sessions.ipynb)
  - [003 - Amazon S3](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/003%20-%20Amazon%20S3.ipynb)
  - [004 - Parquet Datasets](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/004%20-%20Parquet%20Datasets.ipynb)
  - [005 - Glue Catalog](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/005%20-%20Glue%20Catalog.ipynb)
  - [006 - Amazon Athena](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/006%20-%20Amazon%20Athena.ipynb)
  - [007 - Databases (Redshift, MySQL, PostgreSQL, SQL Server and Oracle)](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/007%20-%20Redshift%2C%20MySQL%2C%20PostgreSQL%2C%20SQL%20Server%2C%20Oracle.ipynb)
  - [008 - Redshift - Copy & Unload.ipynb](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/008%20-%20Redshift%20-%20Copy%20%26%20Unload.ipynb)
  - [009 - Redshift - Append, Overwrite and Upsert](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/009%20-%20Redshift%20-%20Append%2C%20Overwrite%2C%20Upsert.ipynb)
  - [010 - Parquet Crawler](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/010%20-%20Parquet%20Crawler.ipynb)
  - [011 - CSV Datasets](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/011%20-%20CSV%20Datasets.ipynb)
  - [012 - CSV Crawler](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/012%20-%20CSV%20Crawler.ipynb)
  - [013 - Merging Datasets on S3](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/013%20-%20Merging%20Datasets%20on%20S3.ipynb)
  - [014 - Schema Evolution](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/014%20-%20Schema%20Evolution.ipynb)
  - [015 - EMR](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/015%20-%20EMR.ipynb)
  - [016 - EMR & Docker](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/016%20-%20EMR%20%26%20Docker.ipynb)
  - [017 - Partition Projection](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/017%20-%20Partition%20Projection.ipynb)
  - [018 - QuickSight](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/018%20-%20QuickSight.ipynb)
  - [019 - Athena Cache](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/019%20-%20Athena%20Cache.ipynb)
  - [020 - Spark Table Interoperability](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/020%20-%20Spark%20Table%20Interoperability.ipynb)
  - [021 - Global Configurations](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/021%20-%20Global%20Configurations.ipynb)
  - [022 - Writing Partitions Concurrently](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/022%20-%20Writing%20Partitions%20Concurrently.ipynb)
  - [023 - Flexible Partitions Filter](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/023%20-%20Flexible%20Partitions%20Filter.ipynb)
  - [024 - Athena Query Metadata](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/024%20-%20Athena%20Query%20Metadata.ipynb)
  - [025 - Redshift - Loading Parquet files with Spectrum](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/025%20-%20Redshift%20-%20Loading%20Parquet%20files%20with%20Spectrum.ipynb)
  - [026 - Amazon Timestream](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/026%20-%20Amazon%20Timestream.ipynb)
  - [027 - Amazon Timestream 2](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/027%20-%20Amazon%20Timestream%202.ipynb)
  - [028 - Amazon DynamoDB](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/028%20-%20DynamoDB.ipynb)
  - [029 - S3 Select](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/029%20-%20S3%20Select.ipynb)
  - [030 - Data Api](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/030%20-%20Data%20Api.ipynb)
  - [031 - OpenSearch](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/031%20-%20OpenSearch.ipynb)
  - [033 - Amazon Neptune](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/033%20-%20Amazon%20Neptune.ipynb)
  - [034 - Distributing Calls Using Ray](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/034%20-%20Distributing%20Calls%20using%20Ray.ipynb)
  - [035 - Distributing Calls on Ray Remote Cluster](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/035%20-%20Distributing%20Calls%20on%20Ray%20Remote%20Cluster.ipynb)
  - [037 - Glue Data Quality](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/037%20-%20Glue%20Data%20Quality.ipynb)
  - [038 - OpenSearch Serverless](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/038%20-%20OpenSearch%20Serverless.ipynb)
  - [039 - Athena Iceberg](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/039%20-%20Athena%20Iceberg.ipynb)
  - [040 - EMR Serverless](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/040%20-%20EMR%20Serverless.ipynb)
  - [041 - Apache Spark on Amazon Athena](https://github.com/aws/aws-sdk-pandas/blob/main/tutorials/041%20-%20Apache%20Spark%20on%20Amazon%20Athena.ipynb)
- [**API Reference**](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html)
  - [Amazon S3](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#amazon-s3)
  - [AWS Glue Catalog](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#aws-glue-catalog)
  - [Amazon Athena](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#amazon-athena)
  - [Amazon Redshift](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#amazon-redshift)
  - [PostgreSQL](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#postgresql)
  - [MySQL](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#mysql)
  - [SQL Server](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#sqlserver)
  - [Oracle](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#oracle)
  - [Data API Redshift](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#data-api-redshift)
  - [Data API RDS](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#data-api-rds)
  - [OpenSearch](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#opensearch)
  - [AWS Glue Data Quality](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#aws-glue-data-quality)
  - [Amazon Neptune](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#amazon-neptune)
  - [DynamoDB](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#dynamodb)
  - [Amazon Timestream](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#amazon-timestream)
  - [Amazon EMR](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#amazon-emr)
  - [Amazon CloudWatch Logs](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#amazon-cloudwatch-logs)
  - [Amazon Chime](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#amazon-chime)
  - [Amazon QuickSight](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#amazon-quicksight)
  - [AWS STS](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#aws-sts)
  - [AWS Secrets Manager](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#aws-secrets-manager)
  - [Global Configurations](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#global-configurations)
  - [Distributed - Ray](https://aws-sdk-pandas.readthedocs.io/en/3.8.0/api.html#distributed-ray)
- [**License**](https://github.com/aws/aws-sdk-pandas/blob/main/LICENSE.txt)
- [**Contributing**](https://github.com/aws/aws-sdk-pandas/blob/main/CONTRIBUTING.md)

## Getting Help

The best way to interact with our team is through GitHub. You can open an [issue](https://github.com/aws/aws-sdk-pandas/issues/new/choose) and choose from one of our templates for bug reports, feature requests...
You may also find help on these community resources:
* The #aws-sdk-pandas Slack [channel](https://join.slack.com/t/aws-sdk-pandas/shared_invite/zt-sxdx38sl-E0coRfAds8WdpxXD2Nzfrg)
* Ask a question on [Stack Overflow](https://stackoverflow.com/questions/tagged/awswrangler)
  and tag it with `awswrangler`
* [Runbook](https://github.com/aws/aws-sdk-pandas/discussions/1815) for AWS SDK for pandas with Ray

## Logging

Enabling internal logging examples:

```py3
import logging
logging.basicConfig(level=logging.INFO, format="[%(name)s][%(funcName)s] %(message)s")
logging.getLogger("awswrangler").setLevel(logging.DEBUG)
logging.getLogger("botocore.credentials").setLevel(logging.CRITICAL)
```

Into AWS lambda:

```py3
import logging
logging.getLogger("awswrangler").setLevel(logging.DEBUG)
```


<picture>
  <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/RocketPy-Team/RocketPy/master/docs/static/RocketPy_Logo_white.png">
  <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/RocketPy-Team/RocketPy/master/docs/static/RocketPy_Logo_black.png">

</picture>

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/RocketPy-Team/rocketpy/blob/master/docs/notebooks/getting_started_colab.ipynb)
[![PyPI](https://img.shields.io/pypi/v/rocketpy?color=g)](https://pypi.org/project/rocketpy/)
[![Documentation Status](https://readthedocs.org/projects/rocketpyalpha/badge/?version=latest)](https://docs.rocketpy.org/en/latest/?badge=latest)
[![codecov](https://codecov.io/gh/RocketPy-Team/RocketPy/graph/badge.svg?token=Ecc3bsHFeP)](https://codecov.io/gh/RocketPy-Team/RocketPy)
[![Contributors](https://img.shields.io/github/contributors/RocketPy-Team/rocketpy)](https://github.com/RocketPy-Team/RocketPy/graphs/contributors)
[![Chat on Discord](https://img.shields.io/discord/765037887016140840?logo=discord)](https://discord.gg/b6xYnNh)
[![Sponsor RocketPy](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/RocketPy-Team)
[![Instagram](https://img.shields.io/badge/Instagram-E4405F?style=flat&logo=instagram&logoColor=white)](https://www.instagram.com/rocketpyteam)
[![LinkedIn](https://img.shields.io/badge/LinkedIn-0077B5?style=flat&logo=linkedin&logoColor=white)](https://www.linkedin.com/company/rocketpy)
[![DOI](https://img.shields.io/badge/DOI-10.1061%2F%28ASCE%29AS.1943--5525.0001331-blue.svg)](http://dx.doi.org/10.1061/%28ASCE%29AS.1943-5525.0001331)

# RocketPy

RocketPy is the next-generation trajectory simulation solution for High-Power Rocketry. The code is written as a [Python](http://www.python.org) library and allows for a complete 6 degrees of freedom simulation of a rocket's flight trajectory, including high-fidelity variable mass effects as well as descent under parachutes. Weather conditions, such as wind profiles, can be imported from sophisticated datasets, allowing for realistic scenarios. Furthermore, the implementation facilitates complex simulations, such as multi-stage rockets, design and trajectory optimization and dispersion analysis.

## Main features

1. **Nonlinear 6 Degrees of Freedom Simulations**
   - Rigorous treatment of mass variation effects
   - Efficiently solved using LSODA with adjustable error tolerances
   - Highly optimized for fast performance

2. **Accurate Weather Modeling**
   - Supports International Standard Atmosphere (1976)
   - Custom atmospheric profiles and Soundings (Wyoming, NOAARuc)
   - Weather forecasts, reanalysis, and ensembles for realistic scenarios

3. **Aerodynamic Models**
   - Optional Barrowman equations for lift coefficients
   - Easy import of drag coefficients from other sources (e.g., CFD simulations)

4. **Parachutes with External Trigger Functions**
   - Test the exact code that will fly
   - Sensor data augmentation with noise for comprehensive parachute simulations

5. **Solid, Hybrid, and Liquid Motors Models**
   - Burn rate and mass variation properties from the thrust curve
   - Define custom rocket tanks based on flux data
   - Support for CSV and ENG file formats

6. **Monte Carlo Simulations**
   - Conduct dispersion analysis and global sensitivity analysis

7. **Flexible and Modular**
   - Perform straightforward engineering analysis (e.g., apogee and lift-off speed as a function of mass)
   - Handle non-standard flights (e.g., parachute drop test from a helicopter)
   - Support multi-stage rockets and custom continuous/discrete control laws
   - Easily create new classes, such as other types of motors

8. **Integration with MATLAB®**
   - Effortlessly run RocketPy from MATLAB®
   - Convert RocketPy results to MATLAB® variables for further processing

These powerful features make RocketPy an indispensable tool for high-power rocket trajectory simulation, catering to enthusiasts, researchers, and engineers in the field of rocketry.

## Validation

RocketPy's features have been validated in our latest [research article published in the Journal of Aerospace Engineering](http://dx.doi.org/10.1061/%28ASCE%29AS.1943-5525.0001331).

The table below shows a comparison between experimental data and the output from RocketPy.
Flight data and rocket parameters used in this comparison were kindly provided by [EPFL Rocket Team](https://github.com/EPFLRocketTeam) and [Notre Dame Rocket Team](https://ndrocketry.weebly.com/).

|         Mission         |    Result Parameter    | RocketPy  | Measured  | Relative Error  |
|:-----------------------:|:-----------------------|:---------:|:---------:|:---------------:|
|   Bella Lui Kaltbrumn   | Apogee altitude (m)    |   461.03  |   458.97  |   **0.45 %**    |
|   Bella Lui Kaltbrumn   | Apogee time (s)        |    10.61  |    10.56  |   **0.47 %**    |
|   Bella Lui Kaltbrumn   | Maximum velocity (m/s) |    86.18  |    90.00  |   **-4.24 %**   |
|   NDRT launch vehicle   | Apogee altitude (m)    | 1,310.44  | 1,320.37  |   **-0.75 %**   |
|   NDRT launch vehicle   | Apogee time (s)        |    16.77  |    17.10  |   **-1.90 %**   |
|   NDRT launch vehicle   | Maximum velocity (m/s) |   172.86  |   168.95  |   **2.31 %**    |

# Documentation

Check out documentation details using the links below:

- [User Guide](https://docs.rocketpy.org/en/latest/user/index.html)
- [Code Documentation](https://docs.rocketpy.org/en/latest/reference/index.html)
- [Development Guide](https://docs.rocketpy.org/en/latest/development/index.html)
- [Technical Documentation](https://docs.rocketpy.org/en/latest/technical/index.html)
- [Flight Examples](https://docs.rocketpy.org/en/latest/examples/index.html)

# Join Our Community!

RocketPy is growing fast! Many university groups and rocket hobbyists have already started using it. The number of stars and forks for this repository is skyrocketing. And this is all thanks to a great community of users, engineers, developers, marketing specialists, and everyone interested in helping.

If you want to be a part of this and make RocketPy your own, join our [Discord](https://discord.gg/b6xYnNh) server today!

# Previewing

You can preview RocketPy's main functionalities by browsing through a sample notebook in [Google Colab](https://colab.research.google.com/github/RocketPy-Team/rocketpy/blob/master/docs/notebooks/getting_started_colab.ipynb). No installation is required!

When you are ready to run RocketPy locally, you can read the *Getting Started* section!

# Getting Started

## Quick Installation

To install RocketPy's latest stable version from PyPI, just open up your terminal and run:

```shell
pip install rocketpy
```

For other installation options, visit our [Installation Docs](https://docs.rocketpy.org/en/latest/user/installation.html).
To learn more about RocketPy's requirements, visit our [Requirements Docs](https://docs.rocketpy.org/en/latest/user/requirements.html).

## Running Your First Simulation

In order to run your first rocket trajectory simulation using RocketPy, you can start a Jupyter Notebook and navigate to the `docs/notebooks` folder. Open `getting_started.ipynb` and you are ready to go. We recommend that you read the [First Simulation](https://docs.rocketpy.org/en/latest/user/first_simulation.html) page to get a complete description.

Otherwise, you may want to create your own script or your own notebook using RocketPy. To do this, let's see how to use RocketPy's four main classes:

- `Environment` - Keeps data related to weather.
- `Motor` - Subdivided into `SolidMotor`, `HybridMotor` and `LiquidMotor`. Keeps data related to rocket motors.
- `Rocket` - Keeps data related to a rocket.
- `Flight` - Runs the simulation and keeps the results.

The following image shows how the four main classes interact with each other:

![Diagram](https://raw.githubusercontent.com/RocketPy-Team/RocketPy/master/docs/static/Fluxogram-Page-2.svg)

A typical workflow starts with importing these classes from RocketPy:

```python
from rocketpy import Environment, Rocket, SolidMotor, Flight
```

An optional step is to import datetime, which is used to define the date of the simulation:

```python
import datetime
```

Then create an Environment object. To learn more about it, you can use:

```python
help(Environment)
```

A sample code is:

```python
env = Environment(
    latitude=32.990254,
    longitude=-106.974998,
    elevation=1400,
)

tomorrow = datetime.date.today() + datetime.timedelta(days=1)

env.set_date(
  (tomorrow.year, tomorrow.month, tomorrow.day, 12), timezone="America/Denver"
) # Tomorrow's date in year, month, day, hour UTC format

env.set_atmospheric_model(type='Forecast', file='GFS')
```

This can be followed up by starting a Solid Motor object. To get help on it, just use:

```python
help(SolidMotor)
```

A sample Motor object can be created by the following code:

```python
Pro75M1670 = SolidMotor(
    thrust_source="data/motors/Cesaroni_M1670.eng",
    dry_mass=1.815,
    dry_inertia=(0.125, 0.125, 0.002),
    center_of_dry_mass_position=0.317,
    grains_center_of_mass_position=0.397,
    burn_time=3.9,
    grain_number=5,
    grain_separation=0.005,
    grain_density=1815,
    grain_outer_radius=0.033,
    grain_initial_inner_radius=0.015,
    grain_initial_height=0.12,
    nozzle_radius=0.033,
    throat_radius=0.011,
    interpolation_method="linear",
    nozzle_position=0,
    coordinate_system_orientation="nozzle_to_combustion_chamber",
)
```

With a Solid Motor defined, you are ready to create your Rocket object. As you may have guessed, to get help on it, use:

```python
help(Rocket)
```

A sample code to create a Rocket is:

```python
calisto = Rocket(
    radius=0.0635,
    mass=14.426,  # without motor
    inertia=(6.321, 6.321, 0.034),
    power_off_drag="data/calisto/powerOffDragCurve.csv",
    power_on_drag="data/calisto/powerOnDragCurve.csv",
    center_of_mass_without_motor=0,
    coordinate_system_orientation="tail_to_nose",
)

buttons = calisto.set_rail_buttons(
    upper_button_position=0.0818,
    lower_button_position=-0.6182,
    angular_position=45,
)

calisto.add_motor(Pro75M1670, position=-1.255)

nose = calisto.add_nose(
    length=0.55829, kind="vonKarman", position=1.278
)

fins = calisto.add_trapezoidal_fins(
    n=4,
    root_chord=0.120,
    tip_chord=0.040,
    span=0.100,
    sweep_length=None,
    cant_angle=0,
    position=-1.04956,
)

tail = calisto.add_tail(
    top_radius=0.0635, bottom_radius=0.0435, length=0.060, position=-1.194656
)
```

You may want to add parachutes to your rocket as well:

```python
main = calisto.add_parachute(
    name="main",
    cd_s=10.0,
    trigger=800,  # ejection altitude in meters
    sampling_rate=105,
    lag=1.5,
    noise=(0, 8.3, 0.5),
)

drogue = calisto.add_parachute(
    name="drogue",
    cd_s=1.0,
    trigger="apogee",  # ejection at apogee
    sampling_rate=105,
    lag=1.5,
    noise=(0, 8.3, 0.5),
)
```

Finally, you can create a Flight object to simulate your trajectory. To get help on the Flight class, use:

```python
help(Flight)
```

To actually create a Flight object, use:

```python
test_flight = Flight(
  rocket=calisto, environment=env, rail_length=5.2, inclination=85, heading=0
)
```

Once the Flight object is created, your simulation is done! Use the following code to get a summary of the results:

```python
test_flight.info()
```

To see all available results, use:

```python
test_flight.all_info()
```

Here is just a quick taste of what RocketPy is able to calculate. There are hundreds of plots and data points computed by RocketPy to enhance your analyses.

![6-DOF Trajectory Plot](https://raw.githubusercontent.com/RocketPy-Team/RocketPy/master/docs/static/rocketpy_example_trajectory.svg)

If you want to see the trajectory on Google Earth, RocketPy acn easily export a KML file for you:

```python
test_flight.export_kml(file_name="test_flight.kml")
```

# Authors and Contributors

This package was originally created by [Giovani Ceotto](https://github.com/giovaniceotto/) as part of his work at [Projeto Jupiter](https://github.com/Projeto-Jupiter/). [Rodrigo Schmitt](https://github.com/rodrigo-schmitt/) was one of the first contributors. Later, [Guilherme Fernandes](https://github.com/Gui-FernandesBR/) and [Lucas Azevedo](https://github.com/lucasfourier/) joined the team to work on the expansion and sustainability of this project.

Since then, the [RocketPy Team](https://github.com/orgs/RocketPy-Team/teams/rocketpy-team) has been growing fast and our contributors are what makes us special!

## Institutional Contributors

RocketPy extends its gratitude to the following institutions for their support and contributions:

        <picture align=top>
            <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/RocketPy-Team/RocketPy/master/docs/static/institutional/projeto_jupiter_dark.png" height="150px">
            <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/RocketPy-Team/RocketPy/master/docs/static/institutional/projeto_jupiter_light.jpg" height="150px">

        </picture>

## Individual Contributors

RocketPy is also indebted to a growing list of individual contributors who actively participate in its development. These include:

[![GitHub Contributors Image](https://contrib.rocks/image?repo=RocketPy-Team/RocketPy)](https://github.com/RocketPy-Team/RocketPy/contributors)

See a [detailed list of contributors](https://github.com/RocketPy-Team/RocketPy/contributors) who are actively working on RocketPy.

## Supporting RocketPy and Contributing

The easiest way to help RocketPy is to demonstrate your support by starring our repository!

[![starcharts stargazers over time](https://starchart.cc/rocketpy-team/rocketpy.svg)](https://starchart.cc/rocketpy-team/rocketpy)

You can also become a [sponsor](https://github.com/sponsors/RocketPy-Team) and help us financially to keep the project going.

If you are actively using RocketPy in one of your projects, reaching out to our core team via [Discord](https://discord.gg/b6xYnNh) and providing feedback can help improve RocketPy a lot!

And if you are interested in going one step further, please read [CONTRIBUTING.md](https://github.com/RocketPy-Team/RocketPy/blob/master/CONTRIBUTING.md) for details on our code of conduct and learn more about how you can contribute to the development of this next-gen trajectory simulation solution for rocketry.

## License

This project is licensed under the MIT License - see the [LICENSE.md](https://github.com/RocketPy-Team/RocketPy/blob/master/LICENSE) file for details

## Release Notes

Want to know which bugs have been fixed and the new features of each version? Check out the [release notes](https://github.com/RocketPy-Team/RocketPy/releases).


# user-statistician

[![user-statistician](https://actions.cicirello.org/images/user-statistician640.png)](#user-statistician)

Check out all of our GitHub Actions: https://actions.cicirello.org/

## About user-statistician [![Mentioned in Awesome README](https://awesome.re/mentioned-badge.svg)](https://github.com/matiassingers/awesome-readme)

| __GitHub Actions__ | [![GitHub release (latest by date)](https://img.shields.io/github/v/release/cicirello/user-statistician?label=Marketplace&logo=GitHub)](https://github.com/marketplace/actions/user-statistician) [![Count of Action Users](https://badgen.net/github/dependents-repo/cicirello/user-statistician?icon=github&label=used%20by)](https://github.com/cicirello/user-statistician/network/dependents) |
| :--- | :--- |
| __Build Status__ | [![build](https://github.com/cicirello/user-statistician/actions/workflows/build.yml/badge.svg)](https://github.com/cicirello/user-statistician/actions/workflows/build.yml) [![samples](https://github.com/cicirello/user-statistician/actions/workflows/generate-samples.yml/badge.svg)](https://github.com/cicirello/user-statistician/actions/workflows/generate-samples.yml) [![CodeQL](https://github.com/cicirello/user-statistician/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/cicirello/user-statistician/actions/workflows/codeql-analysis.yml) |
| __Source Info__ | [![License](https://img.shields.io/github/license/cicirello/user-statistician)](https://github.com/cicirello/user-statistician/blob/main/LICENSE) [![GitHub top language](https://img.shields.io/github/languages/top/cicirello/user-statistician)](https://github.com/cicirello/user-statistician) |
| __Contributors__ | [![GitHub contributors](https://img.shields.io/github/contributors/cicirello/user-statistician)](https://github.com/cicirello/user-statistician/graphs/contributors) [![good first issue](https://img.shields.io/github/issues/cicirello/user-statistician/good%20first%20issue)](https://github.com/cicirello/user-statistician/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) |
| __Support__ | [![GitHub Sponsors](https://img.shields.io/badge/sponsor-30363D?logo=GitHub-Sponsors&logoColor=#EA4AAA)](https://github.com/sponsors/cicirello) [![Liberapay](https://img.shields.io/badge/Liberapay-F6C915?logo=liberapay&logoColor=black)](https://liberapay.com/cicirello) [![Ko-Fi](https://img.shields.io/badge/Ko--fi-F16061?logo=ko-fi&logoColor=white)](https://ko-fi.com/cicirello) |

The [cicirello/user-statistician](https://github.com/cicirello/user-statistician) GitHub
Action generates a detailed visual summary of your activity on GitHub in the form of an SVG,
suitable to display on
your [GitHub Profile README](https://docs.github.com/en/github/setting-up-and-managing-your-github-profile/customizing-your-profile/managing-your-profile-readme).
Although the intended use-case is to generate an SVG image for your GitHub Profile README,
you can also potentially link to the image from a personal website, or from anywhere else
where you'd like to share a summary of your activity on GitHub. The SVG that the action
generates includes statistics for the repositories that
you own, your contribution statistics (e.g., commits, issues, PRs, etc), as well as
the distribution of languages within public repositories that you own.
The user stats image can be customized, including the colors such as with one
of the built-in themes or your own set of custom colors. You can also pick and choose
which sections of the card to include, as well as the order of appearance of
the sections; and you can choose to hide individual stats.

The `user-statistician` action runs entirely here on GitHub.
To use it, you just need to set up a workflow in your GitHub
Profile repository (or technically any repository that you own) on a schedule (daily
should be sufficient), and then add a link to the image in your README. The action
handles committing and pushing the generated image to the repository.

__Features__: The features of the
[cicirello/user-statistician](https://github.com/cicirello/user-statistician)
GitHub Action include the following:
* Generates detailed stats for your GitHub Profile README all in a single SVG.
* Ability to generate separate SVGs for the individual categories of stats
  if you prefer.
* Highly customizable (color themes, custom colors, section ordering, custom title).
* [International](#locale) with option to generate SVG in 30 [languages](#locale).
* Runs entirely here on GitHub.
* Updates the SVG on a schedule of your choice (e.g., daily), rather than
  on-demand when someone views your profile, which has the following advantages:
    * The SVG is simply served when requested, avoiding
      the delay associated with waiting for API queries to gather the data to generate
      the SVG.
    * The API queries associated with generating the SVG happen once per
      cycle of your configured schedule, regardless of how frequently your
      profile is visited, decreasing system load.

__Show Your Support__: If you find the `user-statistician` action useful,
please consider starring the repository; and if you use it for your profile
README, please consider either linking the image to this repository, or
otherwise sharing how it was generated with your profile visitors.

## Table of Contents

The remainder of the documentation is organized into the following sections:
* [Quickstart](#quickstart)
* [Example Workflows and Image Samples](#example-workflows-and-image-samples):
  This section includes workflows to get you started using the action, as well as
  sample images.
* [The Stats](#the-stats): This documents all of the statistics included in the
  SVGs that the action generates.
* [Inputs](#inputs): Documentation of all of the inputs to the action, their
  default values, and the effects they have on the behavior of the action.
* [Outputs](#outputs): Documentation of outputs of the action.
* [All Possible Action Inputs](#all-possible-action-inputs): This section provides
  a workflow that summarizes all of the action's inputs along with their default values.
* [Built With](#built-with): A list of the tools, etc used to develop this action.
* [Blog Posts](#blog-posts): A selection of blog posts about the GitHub Action.
* [Support the Project](#support-the-project): Ways that you can support the project.
* [Contributors](#contributors): Information for potential contributors.
  * [Contributing a Translation](#contributing-a-translation): Detailed instructions
    for contributing a language translation for a new locale, the most common type
	of contribution to this project.

## Quickstart
See the [Quickstart](https://github.com/cicirello/user-statistician/blob/main/quickstart) directory
for ready-to-use workflows and quickstart instructions.

## Example Workflows and Image Samples

This section provides example workflows demonstrating various features
of the action, as well as samples of the corresponding images that they generate.
If you would like to see live examples, in addition to the detailed examples
below, then you can check out [my GitHub profile](https://github.com/cicirello),
as well as [my personal website](https://www.cicirello.org/software/#ghstats),
both of these are updated nightly. The GitHub stats card on my GitHub
profile uses the built-in dark theme, and all other settings are the defaults,
and is generated by
[this workflow file](https://github.com/cicirello/cicirello/blob/master/.github/workflows/userstats.yml).
The stats card on my personal website uses a set of custom colors to match the
color palette of my website, and is generated by
[this workflow file](https://github.com/cicirello/status/blob/main/.github/workflows/userstats.yml).

There are also several ready-to-use workflows and quickstart instructions in
the [Quickstart](https://github.com/cicirello/user-statistician/blob/main/quickstart) directory.

### Example 1: All default inputs

This first example uses all of the default inputs (see [Inputs](#inputs) section
for details of available inputs). Specifically, it uses the default color
theme (a light theme), and includes all available statistics in the image and
the default title. The action commits and pushes the image by default as well.

```yml
name: user-statistician

on:
  schedule:
    - cron: '0 3 * * *'
  workflow_dispatch:

jobs:
  stats:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Generate the user stats image
      uses: cicirello/user-statistician@v1
      env:
        GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
```

This example workflow runs on a schedule (every day at 3am) and also includes
the `workflow_dispatch` event so that you can run it manually if desired.
See GitHub's documentation for details
on [schedule syntax](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#schedule)
and [workflow_dispatch](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch).
The `actions/checkout@v4` step is required because the action generates the stats image
for the owner of the checked out repository, and it is also for the commit and push
functionality. Additionally, the `GITHUB_TOKEN` must be passed via an environment
variable to `cicirello/user-statistician` (see
the `GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}`) in order to be able to query
GitHub's GraphQL API. The default permissions of the `GITHUB_TOKEN` are sufficient
for the API queries as well as (in most cases) for pushing the image to your
repository. If you are running this in a repository with branch
protection rules that require either reviews or checks, then see the section
below on [Protected branches with required checks](#protected-branches-with-required-checks).

The default behavior of the language distribution chart is to explicitly
list all languages that individually make up at least 1% of the code in your
public repositories, with low percentage languages combined into an "Other".
The language distribution chart is intended to be equivalent to the
language charts that GitHub generates for each repository, but by combining
all of the repositories that you own.

Assuming that you use the default image filename and path, then you can
insert the image into your README with the following markdown:

```markdown
![My user statistics](images/userstats.svg)
```

Although not required, it is appreciated if you instead link the image to this repository
so that others know how you generated it, with the following markdown:

```markdown
[![My user statistics](images/userstats.svg)](https://github.com/cicirello/user-statistician)
```

Here is a sample of what this will produce:

[![Default input values uses light theme](https://raw.githubusercontent.com/cicirello/user-statistician/samples/images/light.svg)](https://github.com/cicirello/user-statistician)

### Example 2: Dark theme without title

This example shows how to change colors to the
dark theme, as well as disabling the title.

```yml
name: user-statistician

on:
  schedule:
    - cron: '0 3 * * *'
  workflow_dispatch:

jobs:
  stats:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Generate the user stats image
      uses: cicirello/user-statistician@v1
      with:
        colors: dark
        include-title: false
      env:
        GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
```

Here is a sample of what this will produce:

[![Dark theme without title](https://raw.githubusercontent.com/cicirello/user-statistician/samples/images/dark.svg)](https://github.com/cicirello/user-statistician)

### Example 3: Dark-dimmed theme with custom title, some hidden stats, an animated language chart, and including all languages in language distribution chart

This example shows the dark-dimmed theme, uses a custom title, includes all
languages in language distribution chart, and hides
several statistics (joined, mostStarred, mostForked, followers, following,
and private). Note by hiding joined, mostStarred, mostForked, followers,
and following that the action will automatically hide the header row for the
"General Stats and Info" section since we've hidden all of the non-zero
stats from that section. If someone were to sponsor me, or if I was to
sponsor someone else, then the "General Stats and Info" section will show up the next time
generated since this sample didn't hide the sponsors or sponsoring counts.
If we want to guarantee that this entire section is hidden, we could instead
specify "general" among the "keys" we pass to `hide-keys`.

```yml
name: user-statistician

on:
  schedule:
    - cron: '0 3 * * *'
  workflow_dispatch:

jobs:
  stats:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Generate the user stats image
      uses: cicirello/user-statistician@v1
      with:
        colors: dark-dimmed
        custom-title: My GitHub Statistics
        hide-keys: joined, mostStarred, mostForked, followers, following, private
        max-languages: 100
        animated-language-chart: true
      env:
        GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
```

Here is a sample of what this will produce:

[![Dark-dimmed theme with custom title, animated language chart, and some hidden stats](https://raw.githubusercontent.com/cicirello/user-statistician/samples/images/dark-dimmed.svg)](https://github.com/cicirello/user-statistician)

### Example 4: Multiple SVGs for repository stats, contribution stats, and language distribution

If you would rather have separate SVGs for each type of GitHub stats (repository
stats, contribution stats, and language distribution), then you can accomplish this
by running the action multiple times in a single workflow. This example does this.
Note that you must use the `image-file` input to give each of the SVGs its own
filename in this case, which will likewise change the markdown needed to insert
the images into your readme.

```yml
name: user-statistician

on:
  schedule:
    - cron: '0 3 * * *'
  workflow_dispatch:

jobs:
  stats:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Generate the languages distribution
      uses: cicirello/user-statistician@v1
      with:
        image-file: images/languages.svg
        hide-keys: general, contributions, repositories
      env:
        GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}

    - name: Generate the contributions stats
      uses: cicirello/user-statistician@v1
      with:
        image-file: images/contribs.svg
        hide-keys: general, languages, repositories
      env:
        GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}

    - name: Generate the repositories stats
      uses: cicirello/user-statistician@v1
      with:
        image-file: images/repos.svg
        hide-keys: general, contributions, languages
      env:
        GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
```

### Specific version vs major release

All of the above examples used the major release tag
for the `user-statistician` step
(i.e., `uses: cicirello/user-statistician@v1`):

```yml
    - name: Generate the user stats image
      uses: cicirello/user-statistician@v1
      env:
        GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
```

The advantage to this is that you will automatically
get all non-breaking changes and bug fixes without the
need to alter your workflow. If you prefer to
use a specific release, just use the SemVer of the
release that you wish to use, such as with the following:

```yml
    - name: Generate the user stats image
      uses: cicirello/user-statistician@v1.22.0
      env:
        GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
```

If you do use a specific release, then we recommend
configuring [GitHub's Dependabot](https://github.blog/2020-06-01-keep-all-your-packages-up-to-date-with-dependabot/)
in your repository.  Dependabot can be used to monitor dependencies,
including GitHub Actions, and generates automated pull requests to update
versions. The PRs it generates includes the text of release notes and ChangeLogs
giving you the opportunity to decide whether to upgrade the version.

### Protected branches with required checks

The default permissions of the `GITHUB_TOKEN` are sufficient for pushing
to a protected branch, provided that the branch protection hasn't been
configured with required reviews nor with required checks. If your
GitHub profile repository does have a branch protection rule with
required reviews or required checks, there are a couple solutions.

__Not Recommended:__ First, you could create a personal access token (PAT)
with necessary permissions, save it as a repository secret, and use the PAT
with during the `actions/checkout` step
(see [actions/checkout](https://github.com/actions/checkout)'s documentation).
However, we do not recommend doing so.
If anyone else has write access to the repository, then they can potentially
create additional workflows using that PAT. This is probably reasonably safe
since it is probably rare to have collaborators on ones profile repository.
However, we still do not recommend this approach, as you must have had a reason
to put the required checks in place. If you decide to go this route anyway, note
that the `user-statistician` action will still only need the `GITHUB_TOKEN` and not
the PAT.

__Recommended:__ The second (and recommended) approach to dealing with a
protected branch with
required checks is to set up a dedicated branch for generating the stats image.
This is actually what we are doing in this repository to generate the samples.
Our `main` branch is protected with required checks, after all this is a development
project repository and not a profile repository. We have a separate branch, `samples`,
that is protected, but does not have any required checks. The `GITHUB_TOKEN`
is sufficient to push to this branch.

Here is how you can do something similar if your profile repository has
required checks on its main branch. First, create a branch, perhaps called `stats`.
The special `stats` branch does not need to be kept up to date with `main`. In fact,
once you create the `stats` branch, you can delete everything from that branch (e.g.,
you'll notice that the `samples` branch of this repository only has an "images"
directory). Next, create or modify a workflow in your `main` (or default) branch
that checks out the dedicated `stats` branch (see the modified `actions/checkout`
step) as follows:

```yml
name: user-statistician

on:
  schedule:
    - cron: '0 3 * * *'
  workflow_dispatch:

jobs:
  stats:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
      with:
        ref: stats   # Or whatever you named your dedicated branch

    - name: Generate the user stats image
      uses: cicirello/user-statistician@v1
      env:
        GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
```

Since the image is now in a different branch than your README,
you also need to modify the markdown used to insert the
image into your profile README to refer explicitly to that branch
as follows:

```markdown
![My user statistics](../BRANCHNAME/images/userstats.svg)
```

The relative link in the example above is relative to the branch
of the README that the viewer is viewing, so we can go up one level
with `..` and then into the branch where our SVG resides.

A version that links the image to this repository
so that others know how you generated it is as follows:

```markdown
[![My user statistics](../BRANCHNAME/images/userstats.svg)](https://github.com/cicirello/user-statistician)
```

## The Stats

The statistics displayed in the image are organized into categories. The stats
card can be customized to hide either individual statistics, or entire categories
if desired. Details of each category follows. Note that the "Key" is what you need if
you are using the `hide-keys` input to either hide individual statistics or
entire categories (see the [Inputs](#inputs) section).

### General Stats and Info

The key to hide this entire category is: `general`. The statistics include the
following.

| Key | Statistic | Details |
| --- | --- | ------ |
| `joined` | Year Joined | the year user joined GitHub |
| `featured` | Featured repository | user optionally selects this with an input |
| `mostStarred` | Most starred repository | name of repo |
| `mostForked` | Most forked repository | name of repo |
| `followers` | Followers | simple count |
| `following` | Following | simple count |
| `sponsors` | Sponsors | simple count |
| `sponsoring` | Sponsoring | simple count |

### Repositories

The Repositories category in the image includes
two columns with data summarizing information
about the public non-forks that you own, as well as all public repositories
that you own, including forks.

The key to hide this entire category is: `repositories`.
The statistics include the following.

| Key | Statistic | Details |
| --- | --- | ------ |
| `public` | My Repositories | simple count |
| `starredBy` | Starred By | simple count |
| `forkedBy` | Forked By  | simple count |
| `watchedBy` | Watched By | number watching your repositories |
| `templates` | Templates | number of your repositories that are templates |
| `archived` | Archived | number of your repositories that you have archived |

### Contributions

The Contributions category in the image includes
two columns with data summarizing information
about your contributions during the past year, as well as
totals over all years. The contribution counts are as
reported by the GitHub GraphQL API. For details of how GitHub
counts contributions, see
[GitHub's documentation](https://docs.github.com/en/github/setting-up-and-managing-your-github-profile/managing-contribution-graphs-on-your-profile/why-are-my-contributions-not-showing-up-on-my-profile).
The contribution data included is all public. This is true even
of the "Private Contributions" entry on the stats image, as
the "restrictedContributionsCount" returned from the query executed by the action
will only be non-zero if you have opted in to sharing private contributions via
[GitHub's profile settings](https://docs.github.com/en/github/setting-up-and-managing-your-github-profile/managing-contribution-graphs-on-your-profile/publicizing-or-hiding-your-private-contributions-on-your-profile).
You can also hide the "Private Contributions" entry (see the
[Inputs section](#inputs)) regardless of your GitHub settings, or any of the
other entries. Each statistic will also auto-hide if the count is 0.

The key to hide this entire category is: `contributions`.
The contributions statistics in the image include the following.

| Key | Statistic | Details |
| --- | --- | ------ |
| `commits` | Commits | simple count |
| `issues` | Issues | simple count |
| `prs` | Pull Requests | simple count |
| `reviews` | Pull Request Reviews | simple count |
| `contribTo` | Contributed To | number of repositories owned by others that you have contributed to |
| `private` | Private Contributions | number of private contributions if you have shared them via your GitHub settings |

Note that due to limitations in the available data from the GitHub GraphQL API, the
"Total" column for `contribTo` on the generated SVG is deliberately blank.

Please note that GitHub's "restrictedContributionsCount" (which is your private contributions
count) doesn't distinguish the type of contributions, so we cannot simply add
these to the specific counts by type.

### Language Distribution

The key to hide the language distribution section of the card is: `languages`.

The default behavior of the language distribution chart is to explicitly
list all languages that individually make up at least 1% of the code in your
public repositories, with low percentage languages combined into an "Other".
The language distribution chart is intended to be equivalent to the
language charts that GitHub generates for each repository, but by combining
all of the repositories that you own. The percentages are based on file sizes.
You can also configure the number of languages to explicitly list
(see the [Inputs](#inputs) section).

Here are a few questions that we anticipate you might have:

__Why file sizes?__ Well, that is what GitHub
uses for the language charts within repositories, and that is the data that GitHub's
API makes available to us.

__Why are some of my languages missing?__ There are a variety of reasons that a
language might not be represented. GitHub
uses [Linguist](https://github.com/github/linguist) to detect the language
of each file in your repositories. There are several reasons that it might
exclude either individual files from the analysis, or entire languages.
You can find the full list
in [Linguist's documentation](https://github.com/github/linguist/blob/master/docs/how-linguist-works.md).
Among Linguist's default exclusions are languages classified as "data" and "prose",
as well as generated code, vendored code, and documentation. Some languages
that GitHub classifies as "data" are XML, JSON, GraphQL, among others.
Markdown is among the languages classified as "prose". To see how GitHub has
classified languages, look at
[Linguist's languages.yml](https://github.com/github/linguist/blob/master/lib/linguist/languages.yml).

__Can I include languages that Linguist excludes?__ Yes, you can. GitHub's Linguist
enables you to [configure Linguist on a per-repository basis](https://github.com/github/linguist/blob/master/docs/overrides.md)
via a `.gitattributes` file. In fact, we've done this very thing on this repository
to tell Linguist to include GraphQL (e.g., see our [.gitattributes](https://github.com/cicirello/user-statistician/blob/main/.gitattributes)).

__Can I exclude files or languages that Linguist includes?__ Yes, you can. With this, again
see [Linguist's override documentation](https://github.com/github/linguist/blob/master/docs/overrides.md). For example, Linguist
excludes documentation by default, but perhaps
you have documentation that is not in one of the paths that Linguist normally
treats as documentation. You can use your repository's `.gitattributes` file
to mark files or directories as documentation (likewise for vendored code, generated code,
etc). For an example of this, see the [.gitattributes of one of our other repositories](https://github.com/cicirello/Chips-n-Salsa/blob/master/.gitattributes) where we direct
Linguist to treat a directory as documentation.

__Can I exclude entire repositories from the language stats?__ Yes, the action has an input for
that.  See [Inputs](#inputs) section.

## Inputs

All inputs include default values, and are thus optional provided the
defaults are relevant to your use-case.

### `image-file`

The `image-file` input is the name of the file (including path relative to the
root of the repository) for the user statistics image that is generated
by the action. It defaults to `image-file: images/userstats.svg`. The action
will create any directories that don't already exist, as necessary. The image is
an svg.

### `include-title`

The `include-title` controls whether or not the user statistics card
includes a title. It defaults to `true`. If you'd rather not have a
title in the image, then just pass `include-title: false` (actually, anything
other than `true`, case insensitive, will be treated as `false`).

### `custom-title`

If you include a title in the user statistics image, the default
title is of the form "Your Name's GitHub Activity", where "Your Name" is the
public name of the owner of the repository that is using the action.
Although note that in the case where the API query returns a null name,
then the fallback behavior is to use the user id in its place.

You can customize the title using the `custom-title` input. For example,
`custom-title: Hello GitHub` will set the title accordingly. Be aware that
the image width is fixed, and is not resized based on title length. Note that
if you pass a custom title with the `custom-title` input and also pass
`include-title: false`, then the conflicting input values will be resolved in
favor of the `include-title: false`.

### `small-title`

This input controls the font size of the title. The default is `small-title: false`,
which is a font size of 18px (the font size of the rest of the text in the SVG is 14px).
The default should be a good choice in most cases. However, depending upon the
length of a custom title, or if you use the default title but have a long name, or if
your chosen locale leads to a lengthy title, then
you might consider using a smaller size for the title. If you pass
`small-title: true`, then it will decrease the font size of the title to 16px.

### `featured-repository`

If you want to feature a repository in the General Stats and Info section,
you can use this input to do so. For example, although the action includes
the Most Starred and Most Forked repositories in that section by default,
perhaps there is another repository that you are particularly proud of, or
which you feel is a better representative of your overall work. The default is
nothing featured since it is impossible to predict what you would want here.
To use, just pass the name of the repository via this input. Note that the action
doesn't attempt to validate whether this repository actually exists.

### `max-languages`

This input is the maximum number of languages to explicitly include in
the language distribution chart. The default is `max-languages: auto`, which
will explicitly show all languages that make up at least 1% of the code in your
public repositories (excluding forks). All other languages will be combined
into an "Other". You can also specify the number of languages explicitly.
For example, `max-languages: 5` will explicitly include the 5 languages with the
highest percentages, and will then combine all other languages into an "Other".
Although if your repositories contain 5 or less languages, then "Other" will
not be listed.  If you want to explicitly include all languages that occur
in your repositories, then just pass a high integer value, such as with
`max-languages: 100`.

### `language-repository-exclusions`

This input is a list of repositories to exclude entirely from the language
distribution chart. The default is an empty list. To exclude one or more
directories from the language distribution chart, pass a comma or space
separated list of the repository names. The following example will exclude
repositories named "repo1" and "repo2":

```yml
    - name: Generate the user stats image
      uses: cicirello/user-statistician@v1
      with:
        language-repository-exclusions: repo1, repo2
      env:
        GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
```

If you have many repositories to exclude, you might consider specifying the list
with a multiline YAML string, such as the following example (the `>` is one of
YAML's ways to specify a multiline string):

```yml
    - name: Generate the user stats image
      uses: cicirello/user-statistician@v1
      with:
        language-repository-exclusions: >
          repo1
          repo2
          repo3
      env:
        GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
```

### `animated-language-chart`

This input can be used to enable animation of the languages pie chart.
This feature is disabled by default. You can enable it with: `animated-language-chart: true`.
If enabled, the pie chart will rotate continuously.

### `language-animation-speed`

If you enable the language chart animation using the `animated-language-chart` input,
then you can control the speed of the animation with the `language-animation-speed`
input.  The default is a full rotation in 10 seconds.  Perhaps you want
a slower rotation, such as 20 seconds, then you can pass: `language-animation-speed: 20`.
Or perhaps you want a faster rotation, such as 5 seconds,
then you can pass: `language-animation-speed: 5`.  The input must be an integer.

### `top-icon`

This input control whether an icon is displayed in the top left and top right corners
surrounding the title. It also controls which icon is displayed. First, if you
disable the title altogether with `include-title: false` (see earlier), that also
disables the icon, regardless of how you set `top-icon`. The options for this input
include `default`, `none`, or one of the named icons in the following table. The
default is `top-icon: default` (explained in table below).

| `top-icon` | meaning |
| --- | --- |
| `default` | Use theme-defined icon (see `colors` docs below) or GitHub Octocat if custom colors are used |
| `none` | Disables the icon altogether |
| `bat` | A bat, such as for use around Halloween |
| `github` | The GitHub Octocat, from [Octicons](https://primer.style/octicons/) |
| `pumpkin` | A pumpkin, such as for use around Halloween |

Setting `top-icon` to a named icon from the list above overrides whatever icon is
specified as the default by your chosen theme (see below).

### `colors`

The `colors` input enables you to either select from a set of
built-in color themes, or to define your own set of custom colors.
At the present time, there are nine built-in themes that are based
on GitHub's color palette and themes of the same names. If you want to
know the specific colors used in each of these,
see the source in [src/Colors.py](https://github.com/cicirello/user-statistician/blob/main/src/Colors.py). Also see
the [Example Workflows and Image Samples](#example-workflows-and-image-samples)
section of this readme for a few samples.

The default is `colors: light`. You can change to a different color theme
by just passing its name (e.g., `colors: dark`). Here is a list of the
currently supported built-in themes, along with the default icon (see the documentation of `top-icon` above):

| Theme Name | Default `top-icon` | Dark or Light? |
| --- | --- | --- |
| `batty` | `bat` | light |
| `dark` | `github` | dark |
| `dark-colorblind` | `github` | dark |
| `dark-dimmed` | `github` | dark |
| `dark-high-contrast` | `github` | dark |
| `dark-tritanopia` | `github` | dark |
| `halloween` | `pumpkin` | dark |
| `halloween-light` | `pumpkin` | light |
| `light` | `github` | light |
| `light-colorblind` | `github` | light |
| `light-high-contrast` | `github` | light |
| `light-tritanopia` | `github` | light |

Note that at the present time a couple of these are identical. For example,
`light`, `light-colorblind`, and `light-tritanopia` are currently identical
because the part of GitHub's color palettes from which these themes derive
do not differ. They have been included as valid values for the `colors` input
to the action for consistency.

If you have a specific set of colors that you'd like to instead use, you
can pass a list of colors (space or comma separated). The list should include
at least 4 colors in the following order: background color, border color,
icon color, title color, and (optionally) text color. If only 4 colors are specified,
then all text will use the title color. If you pass more than 5 colors, the extras
are ignored. If you pass less than 4 colors, then the default `light` theme will
be used.  Here is an example: `colors: '#f6f8fa #c8e1ff #0366d6 #24292e #24292e'`.
This example happens to be the `light` theme. Because `#` has special meaning to
YAML (it is used for comments), you must either put quotes around the input value
as shown in this example, or you can escape each `#` individually. The colors in this
list can be specified either with hex (as in the example above), or with any
named colors that are recognized by SVG, or some combination of the two. Here is an
example with named colors: `colors: black yellow green white white`. Notice that you
don't need quotes around the input if none of the colors are specified by hex.

__The action does not do any validation of the colors that you pass.__ If you pass
invalid color names or invalid hex color values, then the image generated will be
incorrect. The color values that you specify are inserted verbatim into the appropriate
places within the SVG.

### `border-radius`

This input is the radius of the border of the SVG. The default is `border-radius: 6`.

### `show-border`

This input controls whether or not the SVG has a border. The default is `true`.

### `image-width`

This input is used to set the minimum width of the SVG. The action
will auto-adjust the width as necessary based on the length of the
title, the length of the section headings, and names of languages in
the language distribution chart. This includes factoring in the specific
headings, labels, etc associated with the chosen locale. The
default, `image-width: 0`, directs the action to strictly base the width
of the SVG on its content. You only need to use this input if you desire
to set a fixed width that is larger.

### `hide-keys`

The action automatically hides any statistics with a value of 0. For example,
if you have no pull requests, the action automatically will hide the pull requests
entry from the image rather than listing it as 0. Otherwise, all supported statistics
are shown by default. If you wish to hide any regardless of whether it has a value of 0,
then just pass a list of the "keys" corresponding to those you want to hide.
The list can be either space or comma separated.
If you want to hide an entire group, including the relevant column headings, then you
can pass the "key" for the category itself. Alternatively, if you
list all of the keys for the elements
of that group, then the entire group, including column headings, will be hidden.
For example, `hide-keys: followers following sponsors sponsoring private` will hide
the "Followers", "Following", "Sponsors", and "Sponsoring" counts from
the "General Stats and Info" section, and thus will also eliminate the column
headings for that entire section, and this will
also hide the "Private Contributions" item from the "Contributions" section.
Another way of accomplishing the same thing is to use the "key" for the category
such as: `hide-keys: general private`.

See earlier in the section [The Stats](#the-stats) for the keys needed for this input.
The keys are case sensitive.

### `category-order`

This input enables customizing the order of the stats categories on the card.
The categories are indicated by their keys, just like in the `hide-keys` input.
The default is: `category-order: general, repositories, contributions, languages`.
You can change the order by passing the list in a different order. For example,
perhaps you want the language chart right after the repositories stats section.
You can do that with: `category-order: general, repositories, languages, contributions`.
This input provides another way of controlling which sections appear on the
card. For example, if all you want are the repositories stats and the languages
chart, you can do that
with: `category-order: repositories, languages` without using the `hide-keys`
input. These two inputs also work in combination. If you use `hide-keys`
to hide a category that you include in the `category-order` input, that category
will be hidden despite being in the `category-order`.

### `locale`

This input is an ISO 639-1 (two character) or ISO 639-2 (three character) language code for the
language used in names of statistics, section and column headings, and default title on the user
stats card. The default is `locale: en`, which is English. If an unsupported locale is passed, then the
action will use the default of "en". The following locales are currently supported:

| locale code | language |
| :--- | :--- |
| hy | Armenian |
| id | Bahasa Indonesia |
| bn | Bengali |
| nl | Dutch |
| en | English |
| fi | Finnish |
| fr | French |
| de | German |
| hi | Hindi |
| hu | Hungarian |
| it | Italian |
| ja | Japanese |
| ko | Korean |
| lt | Lithuanian |
| ml | Malayalam |
| no | Norwegian |
| or | Odia |
| fa | Persian |
| pl | Polish |
| pt | Portuguese |
| ro | Romanian |
| ru | Russian |
| sat | Santali |
| sr | Serbian |
| es | Spanish |
| sv | Swedish |
| tl | Tagalog |
| th | Thai |
| tr | Turkish |
| uk | Ukrainian |

If you are interested in contributing a new locale, see the
section [Contributing a Translation](#contributing-a-translation)
for detailed instructions for doing so.

### `fail-on-error`

This input enables you to control what happens if the
action fails for some reason (e.g., error communicating
with the GitHub GraphQL API, etc). Note that in all of
our testing so far, this has not happened yet. But as software
developers, we all know that anything that can go wrong, will
go wrong eventually.

The default is `fail-on-error: true`, which means that if
an error occurs it will cause the workflow to fail. The rationale
for this default is that the failed workflow will lead to a
GitHub notification so that you know something went wrong.
If you'd rather just let it quietly fail, to most likely correct
itself during the next run, then pass `fail-on-error: false`
(actually anything other than `true` will be treated as `false`).

### `commit-and-push`

The `commit-and-push` input controls whether the action commits
and pushes the generated image upon creation. It defaults to
`commit-and-push: true`. If the user stats image has changed since
last commit, then as long as you are not running this in a detached
head state (such as on a pull request event), the action will commit
and push the new user stats image. If you are in a detached head
state, such as if you were to run this during a pull request
(not sure why you would), then the action will simply and quietly
skip the commit/push without issuing an error.

If your branch is protected with either required reviews or required
checks, then the push will fail with an error. Whether this also
fails your workflow depends on how you have set
the `fail-on-error` input. See the earlier discussion for what you
can do if you wish to use the action in a repository with
that has configured required reviews or required checks:
[Protected branches with required checks](#protected-branches-with-required-checks).

The author of the commit is set to the github-actions bot.

### `commit-message`

The `commit-message` input enables customizing the commit message. The
default is `commit-message: 'Automated change by https://github.com/cicirello/user-statistician'`.

## Outputs

The action has only the following action output variable.

### `exit-code`

If the input `fail-on-error` is set to `false`, then in addition to
quietly failing (i.e., not failing the workflow run), the output `exit-code`
will be set to a non-zero exit code that may be useful in debugging the
issue. If the input `fail-on-error` is set to `true` (the default), your
workflow run won't have the opportunity to check the `exit-code` output.
However, the `exit-code` and a descriptive error message will still be
logged in the workflow output. In either case, if you believe that the
failure is a bug, please include this in any bug reports.

## All Possible Action Inputs

The workflow here shows all possible inputs, with their default
values, and also shows how to access the action's `exit-code`
output if desired.

```yml
name: user-statistician

on:
  schedule:
    - cron: '0 3 * * *'
  workflow_dispatch:

jobs:
  stats:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Generate the user stats image
      id: statsStep # Only needed if you want to check the exit-code
      uses: cicirello/user-statistician@v1
      with:
        image-file: images/userstats.svg
        include-title: true
        custom-title: '' # Defaults to title pattern described earlier
        small-title: false
        featured-repository: '' # Defaults to nothing featured
        max-languages: auto
        language-repository-exclusions: '' # None excluded
        animated-language-chart: false
        language-animation-speed: 10
        top-icon: default
        colors: light
        border-radius: 6
        show-border: true
        image-width: 0
        hide-keys: '' # None hidden
        category-order: general, repositories, contributions, languages
        locale: en
        fail-on-error: true
        commit-and-push: true
        commit-message: 'Automated change by https://github.com/cicirello/user-statistician'
      env:
        GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}

    - name: Check exit code if desired
      run: |
        # Note that if you set fail-on-error to true, you'll
        # never actually get here if an error occurs. But if you
        # set fail-on-error to false, then instead of failing the
        # workflow, the action will output the exit code that would
        # have failed the workflow and you can check it here.
        echo "exitCode = ${{ steps.statsStep.outputs.exit-code }}"
```

## Built With

The `user-statistician` action uses the following:
* Python (implemented almost entirely in Python);
* The [cicirello/pyaction](https://actions.cicirello.org/pyaction/) Docker container image,
  which includes the GitHub CLI installed on a python:3-slim base image (see
  [pyaction's GitHub repository](https://github.com/cicirello/pyaction));
* [The GitHub CLI](https://cli.github.com/);
* [GitHub GraphQL API](https://docs.github.com/en/graphql);
* [GitHub Octicons](https://github.com/primer/octicons) for the icons in the stats image;
* [JSON](https://www.json.org/) for managing the various language translations; and
* We started with our template repository for GitHub Actions implemented in
  Python: [cicirello/python-github-action-template](https://github.com/cicirello/python-github-action-template).

## Blog Posts

Here is a selection of [DEV.to](https://dev.to/) blog posts about the user-statistician:
* [Hacktoberfest 2023 Contributors Wanted: Additional Translations for the user-statistician GitHub Action](https://dev.to/cicirello/hacktoberfest-2023-contributors-wanted-additional-translations-for-the-user-statistician-github-action-3bb5), posted on DEV on September 30, 2023.
* [Hacktoberfest Progress Update: Translation Contributions Still Welcome](https://dev.to/cicirello/hacktoberfest-progress-update-translation-contributions-still-welcome-4aof), posted on DEV on October 12, 2022.
* [Hacktoberfest Language Translation Contributors Wanted for the user-statistician GitHub Action](https://dev.to/cicirello/hacktoberfest-language-translation-contributors-wanted-for-the-user-statistician-github-action-2elg), posted on DEV on September 30, 2022.
* [Halloween Themes for the user-statistician GitHub Action](https://dev.to/cicirello/halloween-themes-for-the-user-statistician-github-action-4do6), posted on DEV on September 28, 2022.
* [Configuring GitHub's Linguist to Improve Repository Language Reporting](https://dev.to/cicirello/configuring-githubs-linguist-to-improve-repository-language-reporting-295b), posted on DEV on August 31, 2022.
* [The user-statistician GitHub Action mentioned in Awesome-README](https://dev.to/cicirello/the-user-statistician-github-action-mentioned-in-awesome-readme-5g3o), posted on DEV on August 25, 2022.
* [Progress and Lessons Learned Internationalizing the user-statistician GitHub Action](https://dev.to/cicirello/progress-and-lessons-learned-internationalizing-the-user-statistician-github-action-2he9), posted on DEV on October 13, 2021.
* [Hacktoberfest Participants Help Us Internationalize the user-statistician GitHub Action](https://dev.to/cicirello/hacktoberfest-participants-help-us-internationalize-the-user-statistician-github-action-2bga), posted on DEV on September 29, 2021.
* [Generate a GitHub stats SVG for your GitHub Profile README in GitHub Actions](https://dev.to/cicirello/generate-a-github-stats-svg-for-your-github-profile-readme-in-github-actions-1iaj), posted on DEV on July 29, 2021.

## Support the Project

You can support the project in a number of ways:
* __Starring__: If you find the `user-statistician` action useful, consider starring the
  repository.
* __Linking or Sharing__: If you use it to generate an SVG for your
  GitHub Profile README, consider
  either linking the image back to this repository, or otherwise sharing
  how you generated the stats SVG.
* __Reporting Issues__: If you find a bug or have a suggestion for a new feature,
  please report it via the [Issue tracker](https://github.com/cicirello/user-statistician/issues).
* __Contributing Code__: If there is an open issue that you think you can help with,
  submit a pull request.
* __Sponsoring__: You can also consider
  [becoming a sponsor](https://github.com/sponsors/cicirello).

## Contributors

If you would like to contribute to the project, please start by reading
our [Contributing Guidelines](https://github.com/cicirello/.github/blob/main/CONTRIBUTING.md)
and our [Code of Conduct](https://github.com/cicirello/.github/blob/main/CODE_OF_CONDUCT.md).
After reading the contributing guidelines and code of conduct, fork the repository, create
a feature branch in your fork, make your changes, and submit a pull request. Please note that
every pull request must be associated with an issue that it addresses. If there is a change
that you would like to propose that doesn't already have an issue, please submit an issue
first.

### Contributing a Translation

The most common type of contribution to this project has been language translations. Here is
step-by-step guidance on how to contribute a translation.
* Is there an [open issue](https://github.com/cicirello/user-statistician/issues?q=is%3Aopen)
  for the language you want to contribute? If so, and if nobody is assigned to it, comment on
  the issue expressing interest, and I will assign you to it (e.g., so we don't have multiple
  people working on the same thing). If there isn't an open issue for it, then submit an issue
  for a feature request for the language. Then comment on your new issue indicating if you are
  interested in contributing the translation (e.g., so I know the difference between just a
  request for a language vs a request with offer to contribute it). I'll then assign you to it.
* Fork the repository, and create a branch in your fork for your proposed translation.
* Find the [ISO 639-1 two-character language
  code](https://www.loc.gov/standards/iso639-2/php/English_list.php) for the language. Some
  languages have both a two-character code and a three-character code in the table at that link.
  In those cases, we are going with the two-character code. But there are some languages that
  only have a three-character ISO-639-2 code, and in those cases we'll use the three-character
  code. For example, one of the currently supported languages is Santali, whose code is `sat`.
* In the [src/StatConfig.py](src/StatConfig.py) file, look for the set `supportedLocales` and
  add a string for the locale code alphabetically.
* Next, within the directory [src/locales](src/locales), create a JSON file named with the locale
  code (in all lowercase) and file extension `.json`. For example, the English version is in
  `en.json`. You might consider starting with a copy of the file for a different language that
  you also know, and then editing the various strings.
* Don't change any of the key fields, since those are used internally.
* Translate the `"titleTemplate"`, the first mapping you see in each of the JSON files. The `{0}`
  that you see in a title template string is a placeholder for where the user's name will go. The
  `"titleTemplate"` is required to have that someplace, or else the test cases will fail.
* Translate the `"categoryLabels"`, which are the headings of each of the sections of the SVG, as
  well as the column headings within those sections. The categories that don't have columns should
  just have `null` for the column headings as you will see in any of the existing JSON files.
* Translate the `"statLabels"`, which are the labels for each individual statistic on the SVG.
* Run the unit tests locally. The test cases will verify that there are strings associated with
  all required keys for all locale codes, although they obviously won't verify that the translations
  are correct. To run the unit tests locally, from the root of the repository,
  execute: `python -B -m unittest tests/tests.py`.  Note that for the tests to include your locale,
  as well as for the Action itself to include your locale, the code for it must be in the
  `supportedLocales` set within [src/StatConfig.py](src/StatConfig.py). See the earlier step on this.
* Despite what the pull request template indicates, you do not need to update the README to document
  the new locale code. We'll do that later at the time a new release is made that includes your new
  locale. The reason not to document it at the time of your PR is that all changes to the README from
  the default branch go live immediately on GitHub's Marketplace, which may confuse users into
  believing the new locale is available before it actually is.

## License

This GitHub action is licensed under the [MIT License](https://github.com/cicirello/user-statistician/blob/main/LICENSE). If you contribute
to the project, you agree that your contributions are likewise licensed through
the MIT License.


# IgKnite

> 🌇 As of 24th February 2024, we have decided to **sunset IgKnite.** It might sound unexpectedly straightforward, but we've taken this decision so that we can take the experience we've gained while building this awesome project and apply it to something that'd carry on it's legacy. It has been a very nice journey, and hopefully you'll stay around for updates. Something's on the way!

[![CodeSee](https://github.com/IgKniteDev/IgKnite/actions/workflows/codesee-arch-diagram.yml/badge.svg)](https://github.com/IgKniteDev/IgKnite/actions/workflows/codesee-arch-diagram.yml)
[![Formatting](https://github.com/IgKniteDev/IgKnite/actions/workflows/formatting.yml/badge.svg)](https://github.com/IgKniteDev/IgKnite/actions/workflows/formatting.yml)
[![Linting](https://github.com/IgKniteDev/IgKnite/actions/workflows/linting.yml/badge.svg)](https://github.com/IgKniteDev/IgKnite/actions/workflows/linting.yml)

---

## Table of Contents

- [Mission](#⚔-our-mission)
- [Features](#🗡-features)
- [Usage](#📝-usage)
- [Contributing](#🔨-contributing)
- [License](#🔖-license)

## ⚔ Mission

Most Discord bots these days are closed-source and incomplete. This is due to every developer having specific goals on what to make with Discord's API. Thus, there has recently not been a fully open-sourced approach to creating Discord bots that are both easy to access and stable at the frontend.

Our mission with IgKnite is to fulfill that gap. Meaning that, we're creating a Discord bot that is aimed at both the moderators of Discord servers and the casual, everyday users. We aim to make the moderation experience easier with simple yet stable, fail-safe commands while also entertaining users with music and a handful of easily accessible commands. All of this while also keeping this project **open-source and free forever!**

## ⚡ Features

- Moderation commands, made creative and easy.
- Low-level & polished music system (support for both YouTube & Spotify).
- Asynchronous code on top of the [disnake](https://github.com/DisnakeDev/disnake) API wrapper.
- A playground all by itself for creative commands.
- Fully open-source including assets.
- No buzz, all buff!

## 📝 Usage

IgKnite has its own [documentation webpage](https://igknitedev.github.io/docs) where you can learn about everything, starting from the commands to even self-hosting the bot on your local computer.

## 🔨 Contributing

If you'd like to add your own features to this project, consider having a look at the [contribution guidelines.](./.github/CONTRIBUTING.md) It contains all the critical information for you to hack and deploy! The official documentation for IgKnite, as hyperlinked in the previous section, also has similar text (possibly more) written within to help you understand the core functionalities of the project. We're eagerly waiting for your contribution! :D

## 🔖 License

Licensed under the [MIT License](LICENSE).


# Azure Network Security

![GitHub](https://img.shields.io/github/license/Azure/Azure-Network-Security?style=plastic)
![GitHub contributors](https://img.shields.io/github/contributors/azure/Azure-Network-Security?color=white&logo=Microsoft%20azure&logoColor=blue&style=plastic)
![GitHub last commit](https://img.shields.io/github/last-commit/azure/Azure-Network-Security)
![GitHub issues](https://img.shields.io/github/issues-raw/azure/Azure-Network-Security)
![GitHub repo size](https://img.shields.io/github/repo-size/azure/Azure-Network-Security?color=white&logo=Microsoft%20azure&logoColor=blue)

Welcome to the Azure Network Security community repository. This repo is designed to help:
- Deploy Azure NetSec resources programmatically using scripts and templates.
- Manage configuration of NetSec resources at scale using scripts, templates, Logic Apps (API), and Azure Policy
- Integrate NetSec resources with other tools, such as Azure Sentinel.
- Discover best practices and interesting techniques.
- Contribute back to your community with samples you create and think others would find useful.

# Other Resources

- [Azure Firewall Docs](https://docs.microsoft.com/en-us/azure/firewall/)
- [Azure Firewall Manager Docs](https://docs.microsoft.com/en-us/azure/firewall-manager/)
- [Azure WAF Docs](https://docs.microsoft.com/en-us/azure/web-application-firewall/)
- [Azure DDoS Protection Docs](https://docs.microsoft.com/en-us/azure/virtual-network/ddos-protection-overview)
- [Azure Networking Feedback](https://feedback.azure.com/forums/217313-networking)
- [Technical Community Blog](https://techcommunity.microsoft.com/t5/azure-network-security-blog/bg-p/AzureNetworkSecurityBlog)

# What's new?
Please find the latest artifacts in this repo on our [What's New Page](https://github.com/Azure/Azure-Network-Security/wiki/What's-New)

# Support
All automations within this repository are provided as is, without SLA or official support. However, if you have an issue please fill out a [bug report](https://github.com/Azure/Azure-Network-Security/issues/new?assignees=&labels=&template=bug_report.md&title=) and reference the automation artifact, so the community can try to solve it.

# Wiki
This project has its own [Wiki](https://github.com/Azure/Azure-Network-Security/wiki) which will provide you with further information about the Azure Network Security community, how to contribute, templates to use and other resources.

# Contributing

This project welcomes contributions and suggestions.  Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.microsoft.com.

## Add in your new or updated contributions to GitHub
Note: If you are a first time contributor to this repository, [Fork the repo](https://docs.github.com/github/getting-started-with-github/fork-a-repo) before cloning.

Brand new or update to a contribution via these methods:
* Submit for review directly on GitHub website
    * Browse to the folder you want to upload your file to
    * Choose Upload Files and browse to your file.
    * You will be required to create your own branch and then submit the Pull Request for review.
* Use [GitHub Desktop](https://help.github.com/en/desktop/getting-started-with-github-desktop) or [Visual Studio](https://visualstudio.microsoft.com/vs/) or [VSCode](https://code.visualstudio.com/?wt.mc_id=DX_841432)
    * [Fork the repo](https://docs.github.com/github/getting-started-with-github/fork-a-repo)
    * [Clone the repo](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/cloning-a-repository)
    * [Create your own branch](https://help.github.com/en/desktop/contributing-to-projects/creating-a-branch-for-your-work)
    * Do your additions/updates in GitHub Desktop
    * [Push your changes to GitHub](https://help.github.com/en/github/using-git/pushing-commits-to-a-remote-repository)

## Pull Request
* After you push your changes, you will need to submit the [Pull Request (PR)](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests)
* After submission, check the [Pull Request](https://github.com/Azure/Azure-Network-Security/pulls) for comments
* Make changes as suggested and update your branch or explain why no change is needed. Resolve the comment when done.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.


# lcr-modules: Standardizing genomic analyses

This project aims to become a collection of standard analytical modules for genomic and transcriptomic data. Too often do we copy-paste from each other’s pipelines, which has several pitfalls. Fortunately, all of these problems can be solved with standardized analytical modules, and the benefits are many.

**Documentation:** https://lcr-modules.readthedocs.io/

**License:** [LICENSE](LICENSE)

## Installing oncopipe

```bash
pip install oncopipe
```

## Modules

![Module levels](images/module_levels.png)


# Praxis

What is Praxis?
Praxis is the layer library for [Pax](https://github.com/google/paxml/). While Praxis is optimized for ML at scale, Praxis has a goal to be usable by other JAX-based ML projects.

Some examples of layers to be folded into Praxis are in the [praxis/layers/](https://github.com/google/praxis/tree/main/praxis/layers) directory.

    Copyright 2022 Google LLC

    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

        https://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.


SNMP library for Python
-----------------------

[![PyPI](https://img.shields.io/pypi/v/pysnmplib.svg?maxAge=2592000)](https://pypi.python.org/pypi/pysnmplib)
[![Python Versions](https://img.shields.io/pypi/pyversions/pysnmplib.svg)](https://pypi.python.org/pypi/pysnmplib/)
[![CI](https://github.com/pysnmp/pysnmp/actions/workflows/build-test-release.yml/badge.svg)](https://github.com/pysnmp/pysnmp/actions/workflows/build-test-release.yml)
[![GitHub license](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/pysnmp/pysnmp/master/LICENSE.rst)

This is a pure-Python, open source and free implementation of v1/v2c/v3
SNMP engine distributed under 2-clause [BSD license](http://snmplabs.com/pysnmp/license.html).

The PySNMP project was initially sponsored by a [PSF](http://www.python.org/psf/) grant.
Thank you!

This version is a fork of Ilya Etingof's project [etingof/pysnmp](https://github.com/etingof/pysnmp). Ilya sadly passed away on 10-Aug-2022. Announcement [here](https://lists.openstack.org/pipermail/openstack-discuss/2022-August/030062.html).  His work is still of great use to the Python community and he will be missed.

Features
--------

* Complete SNMPv1/v2c and SNMPv3 support
* SMI framework for resolving MIB information and implementing SMI
  Managed Objects
* Complete SNMP entity implementation
* USM Extended Security Options support (3DES, 192/256-bit AES encryption)
* Extensible network transports framework (UDP/IPv4, UDP/IPv6)
* Asynchronous socket-based IO API support
* [Asyncio](https://docs.python.org/3/library/asyncio.html) integration
* [PySMI](http://snmplabs.com/pysmi/) integration for dynamic MIB compilation
* Built-in instrumentation exposing protocol engine operations
* Python eggs and py2exe friendly
* 100% Python, works with Python 2.4 though 3.7
* MT-safe (if SnmpEngine is thread-local)

Features, specific to SNMPv3 model include:

* USM authentication (MD5/SHA-1/SHA-2) and privacy (DES/AES) protocols (RFC3414, RFC7860)
* View-based access control to use with any SNMP model (RFC3415)
* Built-in SNMP proxy PDU converter for building multi-lingual
  SNMP entities (RFC2576)
* Remote SNMP engine configuration
* Optional SNMP engine discovery
* Shipped with standard SNMP applications (RC3413)

Download & Install
------------------

The PySNMP software is freely available for download from [PyPI](https://pypi.python.org/pypi/pysnmplib)
and [GitHub](https://github.com/pysnmp/pysnmp.git).

Just run:

```bash
$ pip install pysnmplib
```

To download and install PySNMP along with its dependencies:

<!-- Need to find an alternate location for the links to snmplabs.com -->
* [PyASN1](http://snmplabs.com/pyasn1/)
* [PyCryptodomex](https://pycryptodome.readthedocs.io) (required only if SNMPv3 encryption is in use)
* [PySMI](http://snmplabs.com/pysmi/) (required for MIB services only)

Besides the library, command-line [SNMP utilities](https://github.com/etingof/snmpclitools)
written in pure-Python could be installed via:

```bash
$ pip install snmpclitools
```

and used in the very similar manner as conventional Net-SNMP tools:

```bash
$ snmpget.py -v3 -l authPriv -u usr-md5-des -A authkey1 -X privkey1 demo.snmplabs.com sysDescr.0
SNMPv2-MIB::sysDescr.0 = STRING: Linux zeus 4.8.6.5-smp #2 SMP Sun Nov 13 14:58:11 CDT 2016 i686
```

Examples
--------

PySNMP is designed in a layered fashion. Top-level and easiest to use API is known as
*hlapi*. Here's a quick example on how to SNMP GET:

```python
from pysnmp.hlapi import *

iterator = getCmd(SnmpEngine(),
                  CommunityData('public'),
                  UdpTransportTarget(('demo.snmplabs.com', 161)),
                  ContextData(),
                  ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)))

errorIndication, errorStatus, errorIndex, varBinds = next(iterator)

if errorIndication:  # SNMP engine errors
    print(errorIndication)
else:
    if errorStatus:  # SNMP agent errors
        print('%s at %s' % (errorStatus.prettyPrint(), varBinds[int(errorIndex)-1] if errorIndex else '?'))
    else:
        for varBind in varBinds:  # SNMP response contents
            print(' = '.join([x.prettyPrint() for x in varBind]))
```

This is how to send SNMP TRAP:

```python
from pysnmp.hlapi import *

errorIndication, errorStatus, errorIndex, varBinds = next(
    sendNotification(
        SnmpEngine(OctetString(hexValue='8000000001020304')),
        UsmUserData('usr-sha-aes128', 'authkey1', 'privkey1',
                    authProtocol=usmHMACSHAAuthProtocol,
                    privProtocol=usmAesCfb128Protocol),
        UdpTransportTarget(('demo.snmplabs.com', 162)),
        ContextData(),
        'trap',
        NotificationType(ObjectIdentity('SNMPv2-MIB', 'authenticationFailure'))
    )
)

if errorIndication:
    print(errorIndication)
```

> We maintain publicly available SNMP Agent and TRAP sink at
> [demo.snmplabs.com](http://snmplabs.com/snmpsim/public-snmp-agent-simulator.html). You are
> welcome to use it while experimenting with whatever SNMP software you deal with.

:warning: ***This is no longer the case as the snmplabs.com site is now defunct***

```bash
$ python3 examples/hlapi/asyncore/sync/manager/cmdgen/usm-sha-aes128.py
SNMPv2-MIB::sysDescr.0 = SunOS zeus.snmplabs.com 4.1.3_U1 1 sun4m
$
$ python3 examples//hlapi/asyncore/sync/agent/ntforg/v3-inform.py
SNMPv2-MIB::sysUpTime.0 = 0
SNMPv2-MIB::snmpTrapOID.0 = SNMPv2-MIB::warmStart
SNMPv2-MIB::sysName.0 = system name
```

Other than that, PySNMP is capable to automatically fetch and use required MIBs from HTTP, FTP sites
or local directories. You could configure any MIB source available to you (including
[this one](https://pysnmp.github.io/mibs/asn1/)) for that purpose.

For more example scripts please refer to ~~[examples section](http://snmplabs.com/pysnmp/examples/contents.html#high-level-snmp)~~
at pysnmp web site.

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

Library documentation and examples can be found at the ~~[pysnmp project site](http://snmplabs.com/pysnmp/)~~.

If something does not work as expected, please
[open an issue](https://github.com/pysnmp/pysnmp/issues) at GitHub or
post your question [on Stack Overflow](http://stackoverflow.com/questions/ask) or try browsing pysnmp
[mailing list archives](https://sourceforge.net/p/pysnmp/mailman/pysnmp-users/).

Bug reports and PRs are appreciated! ;-)

Copyright (c) 2005-2019, [Ilya Etingof](https://lists.openstack.org/pipermail/openstack-discuss/2022-August/030062.html). All rights reserved.