generated from roboflow/template-python
-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from roboflow/feature/box-annotator
feature/core-classes-and-functions
- Loading branch information
Showing
24 changed files
with
597 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,82 @@ | ||
# Python Template 🐍 | ||
A template repo holding our common setup for a python project. | ||
|
||
## Installation | ||
|
||
You can install the package using pip | ||
|
||
```bash | ||
pip install -e . | ||
``` | ||
|
||
or for development | ||
|
||
```bash | ||
<div align="center"> | ||
<p> | ||
<a align="center" href="" target="_blank"> | ||
<img | ||
width="850" | ||
src="https://media.roboflow.com/open-source/supervision/roboflow-supervision-banner.png?ik-sdk-version=javascript-1.4.3&updatedAt=1674062891088" | ||
> | ||
</a> | ||
</p> | ||
<br> | ||
|
||
<div align="center"> | ||
<a href="https://youtube.com/roboflow"> | ||
<img | ||
src="https://media.roboflow.com/notebooks/template/icons/purple/youtube.png?ik-sdk-version=javascript-1.4.3&updatedAt=1672949634652" | ||
width="3%" | ||
/> | ||
</a> | ||
<img src="https://github.com/SkalskiP/SkalskiP/blob/master/icons/transparent.png" width="3%"/> | ||
<a href="https://roboflow.com"> | ||
<img | ||
src="https://media.roboflow.com/notebooks/template/icons/purple/roboflow-app.png?ik-sdk-version=javascript-1.4.3&updatedAt=1672949746649" | ||
width="3%" | ||
/> | ||
</a> | ||
<img src="https://github.com/SkalskiP/SkalskiP/blob/master/icons/transparent.png" width="3%"/> | ||
<a href="https://www.linkedin.com/company/roboflow-ai/"> | ||
<img | ||
src="https://media.roboflow.com/notebooks/template/icons/purple/linkedin.png?ik-sdk-version=javascript-1.4.3&updatedAt=1672949633691" | ||
width="3%" | ||
/> | ||
</a> | ||
<img src="https://github.com/SkalskiP/SkalskiP/blob/master/icons/transparent.png" width="3%"/> | ||
<a href="https://docs.roboflow.com"> | ||
<img | ||
src="https://media.roboflow.com/notebooks/template/icons/purple/knowledge.png?ik-sdk-version=javascript-1.4.3&updatedAt=1672949634511" | ||
width="3%" | ||
/> | ||
</a> | ||
<img src="https://github.com/SkalskiP/SkalskiP/blob/master/icons/transparent.png" width="3%"/> | ||
<a href="https://disuss.roboflow.com"> | ||
<img | ||
src="https://media.roboflow.com/notebooks/template/icons/purple/forum.png?ik-sdk-version=javascript-1.4.3&updatedAt=1672949633584" | ||
width="3%" | ||
/> | ||
<img src="https://github.com/SkalskiP/SkalskiP/blob/master/icons/transparent.png" width="3%"/> | ||
<a href="https://blog.roboflow.com"> | ||
<img | ||
src="https://media.roboflow.com/notebooks/template/icons/purple/blog.png?ik-sdk-version=javascript-1.4.3&updatedAt=1672949633605" | ||
width="3%" | ||
/> | ||
</a> | ||
</a> | ||
</div> | ||
|
||
</div> | ||
|
||
## 👋 hello | ||
|
||
A set of easy-to-use utils that will come in handy in any Computer Vision project. **Supervision** is still in | ||
pre-release stage. 🚧 Keep your eyes open for potential bugs and be aware that at this stage our API is still fluid | ||
and may change. | ||
|
||
## 💻 install | ||
|
||
```console | ||
# clone repository and navigate to root directory | ||
git clone [email protected]:roboflow/supervision.git | ||
cd supervision | ||
|
||
# setup python environment and activate it | ||
python3 -m venv venv | ||
source venv/bin/activate | ||
|
||
# install | ||
pip install -e ".[dev]" | ||
``` | ||
|
||
## Structure | ||
|
||
The project has the following structure | ||
|
||
``` | ||
├── .github | ||
│ └── workflows | ||
│ └── test.yml # holds our github action config | ||
├── .gitignore | ||
├── Makefile | ||
├── README.md | ||
├── setup.py | ||
├── src | ||
│ ├── __init__.py | ||
│ ├── hello.py | ||
└── test | ||
└── test_hello.py | ||
``` | ||
|
||
### Code Quality 🧹 | ||
## 🧹 Code Quality | ||
|
||
We provide two handy commands inside the `Makefile`, namely: | ||
|
||
|
@@ -43,54 +85,6 @@ We provide two handy commands inside the `Makefile`, namely: | |
|
||
So far, **there is no types checking with mypy**. See [issue](https://github.com/roboflow-ai/template-python/issues/4). | ||
|
||
### Tests 🧪 | ||
## 🧪 Tests | ||
|
||
[`pytests`](https://docs.pytest.org/en/7.1.x/) is used to run our tests. | ||
|
||
### Publish on PyPi 🚀 | ||
|
||
**Important**: Before publishing, edit `__version__` in [src/__init__](/src/__init__.py) to match the wanted new version. | ||
|
||
We use [`twine`](https://twine.readthedocs.io/en/stable/) to make our life easier. You can publish by using | ||
|
||
``` | ||
export PYPI_USERNAME="you_username" | ||
export PYPI_PASSWORD="your_password" | ||
export PYPI_TEST_PASSWORD="your_password_for_test_pypi" | ||
make publish -e PYPI_USERNAME=$PYPI_USERNAME -e PYPI_PASSWORD=$PYPI_PASSWORD -e PYPI_TEST_PASSWORD=$PYPI_TEST_PASSWORD | ||
``` | ||
|
||
You can also use token for auth, see [pypi doc](https://pypi.org/help/#apitoken). In that case, | ||
|
||
``` | ||
export PYPI_USERNAME="__token__" | ||
export PYPI_PASSWORD="your_token" | ||
export PYPI_TEST_PASSWORD="your_token_for_test_pypi" | ||
make publish -e PYPI_USERNAME=$PYPI_USERNAME -e PYPI_PASSWORD=$PYPI_PASSWORD -e PYPI_TEST_PASSWORD=$PYPI_TEST_PASSWORD | ||
``` | ||
|
||
**Note**: We will try to push to [test pypi](https://test.pypi.org/) before pushing to pypi, to assert everything will work | ||
|
||
### CI/CD 🤖 | ||
|
||
We use [GitHub actions](https://github.com/features/actions) to automatically run tests and check code quality when a new PR is done on `main`. | ||
|
||
On any pull request, we will check the code quality and tests. | ||
|
||
When a new release is created, we will try to push the new code to PyPi. We use [`twine`](https://twine.readthedocs.io/en/stable/) to make our life easier. | ||
|
||
The **correct steps** to create a new realease are the following: | ||
- edit `__version__` in [src/__init__](/src/__init__.py) to match the wanted new version. | ||
- create a new [`tag`](https://git-scm.com/docs/git-tag) with the release name, e.g. `git tag v0.0.1 && git push origin v0.0.1` or from the GitHub UI. | ||
- create a new release from GitHub UI | ||
|
||
The CI will run when you create the new release. | ||
|
||
# Q&A | ||
|
||
## Why no cookiecutter? | ||
This is a template repo, it's meant to be used inside GitHub upon repo creation. | ||
|
||
## Why reinvent the wheel? | ||
|
||
There are several very good templates on GitHub, I prefer to use code we wrote instead of blinding taking the most starred template and having features we don't need. From experience, it's better to keep it simple and general enough for our specific use cases. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,64 @@ | ||
import setuptools | ||
from setuptools import find_packages | ||
import re | ||
from pathlib import Path | ||
|
||
with open("./src/__init__.py", 'r') as f: | ||
content = f.read() | ||
# from https://www.py4u.net/discuss/139845 | ||
version = re.search(r'__version__\s*=\s*[\'"]([^\'"]*)[\'"]', content).group(1) | ||
FILE = Path(__file__).resolve() | ||
PARENT = FILE.parent # root directory | ||
README = (PARENT / "README.md").read_text(encoding="utf-8") | ||
|
||
|
||
def get_version(): | ||
file = PARENT / 'supervision/__init__.py' | ||
return re.search(r'^__version__ = [\'"]([^\'"]*)[\'"]', file.read_text(encoding="utf-8"), re.M)[1] | ||
|
||
with open("README.md", "r") as fh: | ||
long_description = fh.read() | ||
|
||
setuptools.setup( | ||
name="template-python-zuppif#1", | ||
version=version, | ||
author="zuppif", | ||
author_email="[email protected]", | ||
description="<INSERT_DESCRIPTION>", | ||
long_description=long_description, | ||
long_description_content_type="text/markdown", | ||
url="https://www.youtube.com/watch?v=dQw4w9WgXcQ", | ||
name='supervision', | ||
version=get_version(), | ||
author='Piotr Skalski', | ||
author_email='[email protected]', | ||
license='MIT', | ||
description='A set of easy-to-use utils that will come in handy in any Computer Vision project', | ||
long_description=README, | ||
long_description_content_type='text/markdown', | ||
url='https://github.com/roboflow/supervision', | ||
install_requires=[ | ||
# list your requires | ||
'numpy', | ||
'opencv-python' | ||
], | ||
packages=find_packages(exclude=("tests",)), | ||
extras_require={ | ||
"dev": ["flake8", "black==22.3.0", "isort", "twine", "pytest", "wheel"], | ||
'dev': [ | ||
'flake8', | ||
'black==22.3.0', | ||
'isort', | ||
'twine', | ||
'pytest', | ||
'wheel', | ||
'notebook' | ||
], | ||
}, | ||
classifiers=[ | ||
"Programming Language :: Python :: 3", | ||
"License :: OSI Approved :: MIT License", | ||
"Operating System :: OS Independent", | ||
'Intended Audience :: Developers', | ||
'Intended Audience :: Science/Research', | ||
'License :: OSI Approved :: BSD License', | ||
'Programming Language :: Python :: 3', | ||
'Programming Language :: Python :: 3.7', | ||
'Programming Language :: Python :: 3.8', | ||
'Programming Language :: Python :: 3.9', | ||
'Programming Language :: Python :: 3.10', | ||
'Programming Language :: Python :: 3 :: Only', | ||
'Topic :: Software Development', | ||
'Topic :: Scientific/Engineering', | ||
"Topic :: Scientific/Engineering :: Artificial Intelligence", | ||
"Topic :: Scientific/Engineering :: Image Recognition", | ||
'Typing :: Typed', | ||
'Operating System :: Microsoft :: Windows', | ||
'Operating System :: POSIX', | ||
'Operating System :: Unix', | ||
'Operating System :: MacOS' | ||
], | ||
python_requires=">=3.7", | ||
keywords="machine-learning, deep-learning, vision, ML, DL, AI, YOLOv5, YOLOv8, Roboflow", | ||
python_requires='>=3.7', | ||
) |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__version__ = "0.0.2" |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
from __future__ import annotations | ||
|
||
from dataclasses import dataclass | ||
from typing import Tuple | ||
|
||
|
||
@dataclass | ||
class Point: | ||
x: float | ||
y: float | ||
|
||
def as_xy_int_tuple(self) -> Tuple[int, int]: | ||
return int(self.x), int(self.y) | ||
|
||
def as_xy_float_tuple(self) -> Tuple[float, float]: | ||
return self.x, self.y | ||
|
||
|
||
@dataclass | ||
class Vector: | ||
start: Point | ||
end: Point | ||
|
||
def is_in(self, point: Point) -> bool: | ||
v1 = Vector(self.start, self.end) | ||
v2 = Vector(self.start, point) | ||
cross_product = (v1.end.x - v1.start.x) * (v2.end.y - v2.start.y) - ( | ||
v1.end.y - v1.start.y | ||
) * (v2.end.x - v2.start.x) | ||
return cross_product < 0 | ||
|
||
|
||
@dataclass | ||
class Rect: | ||
x: float | ||
y: float | ||
width: float | ||
height: float | ||
|
||
@property | ||
def top_left(self) -> Point: | ||
return Point(x=self.x, y=self.y) | ||
|
||
@property | ||
def bottom_right(self) -> Point: | ||
return Point(x=self.x + self.width, y=self.y + self.height) | ||
|
||
def pad(self, padding) -> Rect: | ||
return Rect( | ||
x=self.x - padding, | ||
y=self.y - padding, | ||
width=self.width + 2 * padding, | ||
height=self.height + 2 * padding, | ||
) |
Empty file.
Oops, something went wrong.