mirror of
https://github.com/tiennm99/serena.git
synced 2026-07-31 22:22:43 +00:00
Initial commit from pymetrius template
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "serena Project",
|
||||
"dockerFile": "../Dockerfile",
|
||||
"workspaceFolder": "/workspaces/serena",
|
||||
"settings": {
|
||||
"terminal.integrated.shell.linux": "/bin/bash",
|
||||
"python.pythonPath": "/usr/local/bin/python",
|
||||
},
|
||||
"extensions": [
|
||||
"ms-python.python",
|
||||
"ms-toolsai.jupyter",
|
||||
"ms-python.vscode-pylance"
|
||||
],
|
||||
"forwardPorts": [],
|
||||
"remoteUser": "root",
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
data
|
||||
logs
|
||||
log
|
||||
test/log
|
||||
docs/jupyter_execute
|
||||
docs/.jupyter_cache
|
||||
docs/_build
|
||||
coverage.xml
|
||||
docker_build_and_run.sh
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
# Common step definitions to be included by other workflows
|
||||
# This way we can centralize the package manager-specific steps
|
||||
|
||||
# Poetry setup steps
|
||||
poetry-setup:
|
||||
- name: Install poetry
|
||||
uses: abatilo/actions-poetry@v2
|
||||
- name: Setup a local virtual environment (if no poetry.toml file)
|
||||
run: |
|
||||
poetry config virtualenvs.create true --local
|
||||
poetry config virtualenvs.in-project true --local
|
||||
- uses: actions/cache@v3
|
||||
name: Define a cache for the virtual environment based on the dependencies lock file
|
||||
with:
|
||||
path: ./.venv
|
||||
key: venv-${{ hashFiles('poetry.lock') }}
|
||||
- name: Install the project dependencies
|
||||
run: |
|
||||
poetry install --with dev
|
||||
|
||||
# UV setup steps
|
||||
uv-setup:
|
||||
- name: Install uv
|
||||
run: pip install uv
|
||||
- uses: actions/cache@v3
|
||||
name: Cache dependencies
|
||||
with:
|
||||
path: ~/.cache/uv
|
||||
key: uv-${{ hashFiles('pyproject.toml') }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
uv venv
|
||||
uv pip install -e ".[dev]"
|
||||
|
||||
# Pixi setup steps
|
||||
pixi-setup:
|
||||
- name: Install pixi
|
||||
uses: prefix-dev/setup-pixi@v0.4.1
|
||||
with:
|
||||
pixi-version: v0.7.0
|
||||
- name: Install dependencies
|
||||
run: pixi install
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
name: Linting, Types and Docs Check
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
id-token: write
|
||||
pages: write
|
||||
actions: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: Cancel previous run
|
||||
uses: styfle/cancel-workflow-action@0.11.0
|
||||
with:
|
||||
access_token: ${{ github.token }}
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.11
|
||||
|
||||
|
||||
# use uv package manager
|
||||
- name: Install uv
|
||||
run: pip install uv
|
||||
- uses: actions/cache@v3
|
||||
name: Cache dependencies
|
||||
with:
|
||||
path: ~/.cache/uv
|
||||
key: uv-${{ hashFiles('pyproject.toml') }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
uv venv
|
||||
uv pip install -e ".[dev]"
|
||||
- name: Lint
|
||||
run: uv run poe lint
|
||||
- name: Types
|
||||
run: uv run poe type-check
|
||||
- name: Docs
|
||||
run: uv run poe doc-build
|
||||
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v2
|
||||
with:
|
||||
path: "docs/_build"
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v2
|
||||
@@ -0,0 +1,27 @@
|
||||
name: Upload Python Package
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: 3.11
|
||||
|
||||
|
||||
- name: Install build and twine
|
||||
run: pip install build twine
|
||||
- name: Build and publish
|
||||
env:
|
||||
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
||||
run: |
|
||||
if [ -z "${PYPI_TOKEN}" ]; then echo "Set the PYPI_TOKEN variable in your repository secrets"; exit 1; fi
|
||||
python -m build
|
||||
python -m twine upload dist/* --username __token__ --password $PYPI_TOKEN
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
name: Tests on Ubuntu
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
cpu:
|
||||
runs-on: ubuntu-latest
|
||||
if: "!contains(github.event.head_commit.message, 'ci skip')"
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.11"]
|
||||
steps:
|
||||
- name: Cancel previous run
|
||||
uses: styfle/cancel-workflow-action@0.11.0
|
||||
with:
|
||||
access_token: ${{ github.token }}
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "${{ matrix.python-version }}"
|
||||
|
||||
# Include the appropriate package manager steps based on the selection
|
||||
|
||||
- name: Setup and install dependencies with UV
|
||||
uses: ./.github/workflows/common_steps.yml
|
||||
with:
|
||||
steps: uv-setup
|
||||
- name: Test with pytest
|
||||
run: uv run poe test
|
||||
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
token: ${{ secrets.CODECOV }}
|
||||
file: ./coverage.xml
|
||||
flags: unittests
|
||||
name: codecov-umbrella
|
||||
fail_ci_if_error: false
|
||||
@@ -0,0 +1,39 @@
|
||||
name: Tests on Windows and MacOS
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
cpu-extra:
|
||||
runs-on: ${{ matrix.os }}
|
||||
if: "!contains(github.event.head_commit.message, 'ci skip')"
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest]
|
||||
python-version: [3.11]
|
||||
steps:
|
||||
- name: Cancel previous run
|
||||
uses: styfle/cancel-workflow-action@0.11.0
|
||||
with:
|
||||
access_token: ${{ github.token }}
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
|
||||
# use uv package manager
|
||||
- name: Install uv
|
||||
run: pip install uv
|
||||
- uses: actions/cache@v3
|
||||
name: Cache dependencies
|
||||
with:
|
||||
path: ~/.cache/uv
|
||||
key: uv-${{ hashFiles('pyproject.toml') }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
uv venv
|
||||
uv pip install -e ".[dev]"
|
||||
- name: Test with pytest
|
||||
run: uv run poe test-subset
|
||||
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
#
|
||||
.idea
|
||||
temp
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# reports
|
||||
pylint.html
|
||||
.pylint.d
|
||||
@@ -0,0 +1,52 @@
|
||||
default_install_hook_types: [commit-msg, pre-commit]
|
||||
default_stages: [commit, manual]
|
||||
fail_fast: false
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.4.0
|
||||
hooks:
|
||||
- id: check-added-large-files
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: ruff
|
||||
name: ruff
|
||||
entry: poetry run ruff
|
||||
require_serial: true
|
||||
language: system
|
||||
types: [python]
|
||||
- id: ruff-nb
|
||||
name: ruff-nb
|
||||
entry: poetry run nbqa ruff .
|
||||
require_serial: true
|
||||
language: system
|
||||
pass_filenames: false
|
||||
types: [python]
|
||||
- id: black
|
||||
name: black
|
||||
entry: poetry run black
|
||||
require_serial: true
|
||||
language: system
|
||||
types: [python]
|
||||
- id: poetry-check
|
||||
name: poetry check
|
||||
entry: poetry check
|
||||
language: system
|
||||
files: pyproject.toml
|
||||
pass_filenames: false
|
||||
- id: poetry-lock-check
|
||||
name: poetry lock check
|
||||
entry: poetry check
|
||||
args: [--lock]
|
||||
language: system
|
||||
pass_filenames: false
|
||||
- id: mypy
|
||||
name: mypy
|
||||
entry: poetry run mypy src
|
||||
# filenames should not be passed as they would collide with the config in pyproject.toml
|
||||
pass_filenames: false
|
||||
files: '^src(/[^/]*)*/[^/]*\.py$'
|
||||
language: system
|
||||
- id: mypy-nb
|
||||
name: mypy-nb
|
||||
entry: poetry run nbqa mypy
|
||||
language: system
|
||||
@@ -0,0 +1,10 @@
|
||||
# Changelog
|
||||
|
||||
## 0.1.0 - Initial Release
|
||||
|
||||
### Features:
|
||||
|
||||
### Development:
|
||||
|
||||
- Initial setup by pymetrius
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
# Use the official Python image for the base image.
|
||||
FROM python:3.11-slim
|
||||
|
||||
# Set environment variables to make Python print directly to the terminal and avoid .pyc files.
|
||||
ENV PYTHONUNBUFFERED 1
|
||||
ENV PYTHONDONTWRITEBYTECODE 1
|
||||
|
||||
# Install system dependencies required for package manager and build tools.
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
curl \
|
||||
build-essential \
|
||||
git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install pipx.
|
||||
RUN python3 -m pip install --no-cache-dir pipx \
|
||||
&& pipx ensurepath
|
||||
|
||||
# Add local bin to the path
|
||||
ENV PATH="${PATH}:/root/.local/bin"
|
||||
|
||||
|
||||
# Install the latest version of uv
|
||||
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
|
||||
# Set the working directory
|
||||
WORKDIR /workspaces/serena
|
||||
|
||||
# Copy the pyproject.toml file into the image.
|
||||
COPY pyproject.toml /workspaces/serena/
|
||||
|
||||
# Create virtual environment and install dependencies
|
||||
RUN uv venv
|
||||
RUN uv pip install -e ".[dev]"
|
||||
ENV PATH="/workspaces/serena/.venv/bin:${PATH}"
|
||||
|
||||
# Entrypoint to ensure environment is activated
|
||||
ENTRYPOINT ["/bin/bash", "-c", "source .venv/bin/activate && $0 $@"]
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# serena
|
||||
|
||||
Welcome to the serena library!
|
||||
|
||||
## Getting Started
|
||||
|
||||
You can have a local uv or docker-interpeter based setup. The repository is also
|
||||
configured to seamlessly working within a GitHub Codespace. See the instructions
|
||||
for the various setup scenarios below.
|
||||
|
||||
Independently of how the setup was done, the virtual environment can be activated with
|
||||
`source .venv/bin/activate` (after creating it with uv) and the various tasks like formatting, testing, and documentation building
|
||||
can be executed using `poe`. For example, `poe format` will format the code, including the
|
||||
notebooks. Just run `poe` to see the available commands.
|
||||
|
||||
### Python (uv) setup
|
||||
|
||||
You can install the dependencies with
|
||||
|
||||
```shell
|
||||
uv venv
|
||||
uv pip install -e ".[dev]"
|
||||
source .venv/bin/activate
|
||||
```
|
||||
|
||||
### Docker setup
|
||||
|
||||
Build the docker image with
|
||||
|
||||
```shell
|
||||
docker build -t serena .
|
||||
```
|
||||
|
||||
and run it with the repository mounted as a volume:
|
||||
|
||||
```shell
|
||||
docker run -it --rm -v "$(pwd)":/workspace serena
|
||||
```
|
||||
|
||||
You can also just run `bash docker_build_and_run.sh`, which will do both things
|
||||
for you.
|
||||
|
||||
Note: for the WSL subsystem on Windows you might need to adjust the path for the
|
||||
volume.
|
||||
|
||||
### Codespaces
|
||||
|
||||
The fastest way to get started is to use a GitHub Codespace. Just click on the
|
||||
button in the repository's main page.
|
||||
|
||||
## Contributing
|
||||
Please open new issues for bugs, feature requests and extensions. See more details about the structure and
|
||||
workflow in the [contributing page](docs/04_contributing/04_contributing.rst).
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
docker build -t serena .
|
||||
|
||||
docker run -it --rm -v "$(pwd)":/workspace serena
|
||||
@@ -0,0 +1,5 @@
|
||||
/03_api/*
|
||||
jupyter_execute
|
||||
_toc.yml
|
||||
.jupyter_cache
|
||||
conf.py
|
||||
@@ -0,0 +1,11 @@
|
||||
Example
|
||||
=======
|
||||
This is a placeholder for the example.
|
||||
|
||||
Citation example
|
||||
----------------
|
||||
It contains an example of citation :cite:`TURING.1950`.
|
||||
|
||||
.. bibliography:: /refs.bib
|
||||
:style: unsrtalpha
|
||||
:filter: docname in docnames
|
||||
@@ -0,0 +1,2 @@
|
||||
Tutorials
|
||||
=========
|
||||
@@ -0,0 +1,4 @@
|
||||
# Notebook Tutorials
|
||||
|
||||
Here is a collection of executable tutorials for serena.
|
||||
You can run them directly in colab, or download them and run them locally.
|
||||
@@ -0,0 +1,128 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# The role of notebooks\n",
|
||||
"\n",
|
||||
"Notebooks are great for illustrations and examples that at the same time serve as integration tests.\n",
|
||||
"In this library template, notebooks will be executed with pytest (thus on every\n",
|
||||
"commit in your CI/CD pipeline). The results of the executions will be saved to the docs directory and converted to\n",
|
||||
"static websites through nbconvert. The static websites are then added to the documentation under the\n",
|
||||
"_Guides and Tutorials_ section. These websites will be deployed to Github pages on push to develop."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Before running the notebook\n",
|
||||
"\n",
|
||||
"Install the library and its dependencies with, if you haven't done so already\n",
|
||||
"```\n",
|
||||
"poetry install\n",
|
||||
"```\n",
|
||||
"from the root directory. You can also execute this command directly in the notebook but will need to reload the\n",
|
||||
"kernel afterwards"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"pycharm": {
|
||||
"name": "#%%\n"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Here an illustration of your library\n",
|
||||
"from serena.sample_package.sample_module import hello_stranger\n",
|
||||
"\n",
|
||||
"hello_stranger()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"pycharm": {
|
||||
"name": "#%% md\n"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"## Interactive Documentation\n",
|
||||
"\n",
|
||||
"Note that since notebooks are rendered to html+javascript, you can embed interactive components like maps, videos and\n",
|
||||
"widgets into your documentation, as long as the interaction does not require re-execution of cells.\n",
|
||||
"Below an example of an interactive map created with plotly {cite}`PlotlyMaps`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"pycharm": {
|
||||
"name": "#%%\n"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# slightly adjusted example from https://plotly.com/python/mapbox-layers/\n",
|
||||
"import pandas as pd\n",
|
||||
"import plotly.express as px\n",
|
||||
"\n",
|
||||
"us_cities = pd.read_csv(\n",
|
||||
" \"https://raw.githubusercontent.com/plotly/datasets/master/us-cities-top-1k.csv\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"fig = px.scatter_mapbox(\n",
|
||||
" us_cities,\n",
|
||||
" lat=\"lat\",\n",
|
||||
" lon=\"lon\",\n",
|
||||
" hover_name=\"City\",\n",
|
||||
" hover_data=[\"State\", \"Population\"],\n",
|
||||
" color_discrete_sequence=[\"fuchsia\"],\n",
|
||||
" zoom=3,\n",
|
||||
" height=300,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"fig.update_layout(mapbox_style=\"open-street-map\", margin={\"r\": 0, \"t\": 0, \"l\": 0, \"b\": 0})\n",
|
||||
"fig.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"```{bibliography}\n",
|
||||
":style: unsrtalpha\n",
|
||||
":filter: docname in docnames\n",
|
||||
"```"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 2
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython2",
|
||||
"version": "2.7.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
Contributing to serena
|
||||
=============================================
|
||||
|
||||
|
||||
Install Develop Version
|
||||
-----------------------
|
||||
|
||||
serena is built and managed by `poetry <https://python-poetry.org/>`_. For example,
|
||||
to install all relevant requirements in editable mode you can simply call
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ poetry install --with dev
|
||||
|
||||
|
||||
PEP8 Code Style Check and Formatting
|
||||
----------------------------------------
|
||||
|
||||
Please set up pre-commit by running
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ pre-commit install
|
||||
|
||||
in the main directory. This should make sure that your contribution is properly
|
||||
formatted before every commit.
|
||||
|
||||
The code is inspected and formatted by `black` and `ruff`. They are executed as
|
||||
pre-commit hooks. In addition, `poe the poet` tasks are configured.
|
||||
Simply run `poe` to see the available tasks.
|
||||
E.g, to format and check the linting manually you can run:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ poe format
|
||||
$ poe lint
|
||||
|
||||
|
||||
Type Check
|
||||
----------
|
||||
|
||||
We use `mypy <https://github.com/python/mypy/>`_ to check the type annotations. To check, in the main directory, run:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ poe type-check
|
||||
|
||||
|
||||
Test Locally
|
||||
------------
|
||||
|
||||
This command will run automatic tests in the main directory
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ poe test
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
Documentations are written under the ``docs/`` directory as ReStructuredText (``.rst``) files. ``index.rst`` is the main page. A Tutorial on ReStructuredText can be found `here <https://pythonhosted.org/an_example_pypi_project/sphinx.html>`_.
|
||||
|
||||
API References are automatically generated by `Sphinx <http://www.sphinx-doc.org/en/stable/>`_ according to the outlines under ``docs/api/`` and should be modified when any code changes.
|
||||
|
||||
To compile documentation into webpage, run
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ poe doc-build
|
||||
|
||||
The generated webpage is in ``docs/_build`` and can be viewed with browser (http://0.0.0.0:8000/).
|
||||
|
||||
|
||||
Documentation Generation Test
|
||||
-----------------------------
|
||||
|
||||
We have the following three documentation tests:
|
||||
|
||||
1. pydocstyle (as part of ruff): test all docstrings;
|
||||
|
||||
2. doc8 (as part of ruff): test ReStructuredText format;
|
||||
|
||||
3. sphinx spelling and test: test if there is any error/warning when generating front-end html documentation.
|
||||
|
||||
To check, in the main directory, run:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ poe lint
|
||||
$ poe doc-build
|
||||
@@ -0,0 +1,147 @@
|
||||
# Book settings
|
||||
# Learn more at https://jupyterbook.org/customize/config.html
|
||||
|
||||
#######################################################################################
|
||||
# A default configuration that will be loaded for all jupyter books
|
||||
# Users are expected to override these values in their own `_config.yml` file.
|
||||
# This is also the "master list" of all allowed keys and values.
|
||||
|
||||
#######################################################################################
|
||||
# Book settings
|
||||
title : serena Documentation # The title of the book. Will be placed in the left navbar.
|
||||
author : serena contributors # The author of the book
|
||||
copyright : "" # Copyright year to be placed in the footer
|
||||
logo : "" # A path to the book logo
|
||||
# Patterns to skip when building the book. Can be glob-style (e.g. "*skip.ipynb")
|
||||
exclude_patterns : ['**.ipynb_checkpoints', '.DS_Store', 'Thumbs.db', '_build', 'jupyter_execute', '.jupyter_cache', '.pytest_cache', 'docs/autogen_rst.py', 'docs/create_toc.py']
|
||||
# Auto-exclude files not in the toc
|
||||
only_build_toc_files : false
|
||||
|
||||
#######################################################################################
|
||||
# Execution settings
|
||||
execute:
|
||||
execute_notebooks : cache # Whether to execute notebooks at build time. Must be one of ("auto", "force", "cache", "off")
|
||||
cache : "" # A path to the jupyter cache that will be used to store execution artifacts. Defaults to `_build/.jupyter_cache/`
|
||||
exclude_patterns : [] # A list of patterns to *skip* in execution (e.g. a notebook that takes a really long time)
|
||||
timeout : -1 # The maximum time (in seconds) each notebook cell is allowed to run.
|
||||
run_in_temp : false # If `True`, then a temporary directory will be created and used as the command working directory (cwd),
|
||||
# otherwise the notebook's parent directory will be the cwd.
|
||||
allow_errors : false # If `False`, when a code cell raises an error the execution is stopped, otherwise all cells are always run.
|
||||
stderr_output : show # One of 'show', 'remove', 'remove-warn', 'warn', 'error', 'severe'
|
||||
|
||||
#######################################################################################
|
||||
# Parse and render settings
|
||||
parse:
|
||||
myst_enable_extensions: # default extensions to enable in the myst parser. See https://myst-parser.readthedocs.io/en/latest/using/syntax-optional.html
|
||||
- amsmath
|
||||
- colon_fence
|
||||
# - deflist
|
||||
- dollarmath
|
||||
# - html_admonition
|
||||
# - html_image
|
||||
- linkify
|
||||
# - replacements
|
||||
# - smartquotes
|
||||
- substitution
|
||||
- tasklist
|
||||
myst_url_schemes: [ mailto, http, https ] # URI schemes that will be recognised as external URLs in Markdown links
|
||||
myst_dmath_double_inline: true # Allow display math ($$) within an inline context
|
||||
|
||||
#######################################################################################
|
||||
# HTML-specific settings
|
||||
html:
|
||||
favicon : "" # A path to a favicon image
|
||||
use_edit_page_button : false # Whether to add an "edit this page" button to pages. If `true`, repository information in repository: must be filled in
|
||||
use_repository_button : false # Whether to add a link to your repository button
|
||||
use_issues_button : false # Whether to add an "open an issue" button
|
||||
use_multitoc_numbering : true # Continuous numbering across parts/chapters
|
||||
extra_footer : ""
|
||||
google_analytics_id : "" # A GA id that can be used to track book views.
|
||||
home_page_in_navbar : true # Whether to include your home page in the left Navigation Bar
|
||||
baseurl : "https://github.com/oraios/serena"
|
||||
analytics:
|
||||
|
||||
comments:
|
||||
hypothesis : false
|
||||
utterances : false
|
||||
announcement : "" # A banner announcement at the top of the site.
|
||||
|
||||
#######################################################################################
|
||||
# LaTeX-specific settings
|
||||
latex:
|
||||
latex_engine : pdflatex # one of 'pdflatex', 'xelatex' (recommended for unicode), 'luatex', 'platex', 'uplatex'
|
||||
use_jupyterbook_latex : true # use sphinx-jupyterbook-latex for pdf builds as default
|
||||
targetname : book.tex
|
||||
# Add a bibtex file so that we can create citations
|
||||
bibtex_bibfiles:
|
||||
- refs.bib
|
||||
|
||||
#######################################################################################
|
||||
# Launch button settings
|
||||
launch_buttons:
|
||||
notebook_interface : classic # The interface interactive links will activate ["classic", "jupyterlab"]
|
||||
binderhub_url : "" # The URL of the BinderHub (e.g., https://mybinder.org)
|
||||
jupyterhub_url : "" # The URL of the JupyterHub (e.g., https://datahub.berkeley.edu)
|
||||
thebe : false # Add a thebe button to pages (requires the repository to run on Binder)
|
||||
colab_url : "https://colab.research.google.com"
|
||||
|
||||
repository:
|
||||
url : https://github.com/oraios/serena # The URL to your book's repository
|
||||
path_to_book : docs # A path to your book's folder, relative to the repository root.
|
||||
branch : main # Which branch of the repository should be used when creating links
|
||||
|
||||
#######################################################################################
|
||||
# Advanced and power-user settings
|
||||
sphinx:
|
||||
extra_extensions :
|
||||
- sphinx.ext.autodoc
|
||||
- sphinx.ext.viewcode
|
||||
- sphinx_toolbox.more_autodoc.sourcelink
|
||||
- sphinxcontrib.spelling
|
||||
local_extensions : # A list of local extensions to load by sphinx specified by "name: path" items
|
||||
recursive_update : false # A boolean indicating whether to overwrite the Sphinx config (true) or recursively update (false)
|
||||
config : # key-value pairs to directly over-ride the Sphinx configuration
|
||||
autodoc_typehints_format: "short"
|
||||
autodoc_member_order: "bysource"
|
||||
autoclass_content: "both"
|
||||
autodoc_default_options:
|
||||
show-inheritance: True
|
||||
suppress_warnings: ["mystnb.unknown_mime_type"] # needed for plotly rendering
|
||||
autodoc_show_sourcelink: True
|
||||
add_module_names: False
|
||||
github_username: oraios
|
||||
github_repository: https://github.com/oraios/serena
|
||||
python_use_unqualified_type_names: True
|
||||
nb_mime_priority_overrides: [
|
||||
[ 'html', 'application/vnd.jupyter.widget-view+json', 10 ],
|
||||
[ 'html', 'application/javascript', 20 ],
|
||||
[ 'html', 'text/html', 30 ],
|
||||
[ 'html', 'text/latex', 40 ],
|
||||
[ 'html', 'image/svg+xml', 50 ],
|
||||
[ 'html', 'image/png', 60 ],
|
||||
[ 'html', 'image/jpeg', 70 ],
|
||||
[ 'html', 'text/markdown', 80 ],
|
||||
[ 'html', 'text/plain', 90 ],
|
||||
[ 'spelling', 'application/vnd.jupyter.widget-view+json', 10 ],
|
||||
[ 'spelling', 'application/javascript', 20 ],
|
||||
[ 'spelling', 'text/html', 30 ],
|
||||
[ 'spelling', 'text/latex', 40 ],
|
||||
[ 'spelling', 'image/svg+xml', 50 ],
|
||||
[ 'spelling', 'image/png', 60 ],
|
||||
[ 'spelling', 'image/jpeg', 70 ],
|
||||
[ 'spelling', 'text/markdown', 80 ],
|
||||
[ 'spelling', 'text/plain', 90 ],
|
||||
]
|
||||
mathjax_path: https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js
|
||||
mathjax3_config:
|
||||
loader: { load: [ '[tex]/configmacros' ] }
|
||||
tex:
|
||||
packages: { '[+]': [ 'configmacros' ] }
|
||||
macros:
|
||||
vect: ["{\\mathbf{\\boldsymbol{#1}} }", 1]
|
||||
E: "{\\mathbb{E}}"
|
||||
P: "{\\mathbb{P}}"
|
||||
R: "{\\mathbb{R}}"
|
||||
abs: ["{\\left| #1 \\right|}", 1]
|
||||
simpl: ["{\\Delta^{#1} }", 1]
|
||||
amax: "{\\text{argmax}}"
|
||||
Vendored
+138
@@ -0,0 +1,138 @@
|
||||
body {
|
||||
font-family: "Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;
|
||||
}
|
||||
|
||||
/* Default header fonts are ugly */
|
||||
h1, h2, .rst-content .toctree-wrapper p.caption, h3, h4, h5, h6, legend, p.caption {
|
||||
font-family: "Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;
|
||||
}
|
||||
|
||||
/* Use white for docs background */
|
||||
.wy-side-nav-search {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.wy-nav-content {
|
||||
max-width: 1200px !important;
|
||||
}
|
||||
|
||||
.wy-nav-content-wrap, .wy-menu li.current > a {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.wy-side-nav-search>a img.logo {
|
||||
width: 80%;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1400px) {
|
||||
.wy-nav-content-wrap {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.wy-nav-content {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fixes for mobile */
|
||||
.wy-nav-top {
|
||||
background-color: #fff;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
padding: 0;
|
||||
margin: 0.4045em 0.809em;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.wy-nav-top > a {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.wy-side-nav-search>a img.logo {
|
||||
height: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
/* This is needed to ensure that logo above search scales properly */
|
||||
.wy-side-nav-search a {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* This ensures that multiple constructors will remain in separate lines. */
|
||||
.rst-content dl:not(.docutils) dt {
|
||||
display: table;
|
||||
}
|
||||
|
||||
/* Use our red for literals (it's very similar to the original color) */
|
||||
.rst-content tt.literal, .rst-content tt.literal, .rst-content code.literal {
|
||||
color: #4692BC;
|
||||
}
|
||||
|
||||
.rst-content tt.xref, a .rst-content tt, .rst-content tt.xref,
|
||||
.rst-content code.xref, a .rst-content tt, a .rst-content code {
|
||||
color: #404040;
|
||||
}
|
||||
|
||||
/* Change link colors (except for the menu) */
|
||||
|
||||
a {
|
||||
color: #4692BC;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #4692BC;
|
||||
}
|
||||
|
||||
|
||||
a:visited {
|
||||
color: #4692BC;
|
||||
}
|
||||
|
||||
.wy-menu a {
|
||||
color: #b3b3b3;
|
||||
}
|
||||
|
||||
.wy-menu a:hover {
|
||||
color: #b3b3b3;
|
||||
}
|
||||
|
||||
/* Default footer text is quite big */
|
||||
footer {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
footer .rst-footer-buttons {
|
||||
font-size: 125%; /* revert footer settings - 1/80% = 125% */
|
||||
}
|
||||
|
||||
footer p {
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
.ethical-rtd {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ethical-fixedfooter {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ethical-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* For hidden headers that appear in TOC tree */
|
||||
/* see http://stackoverflow.com/a/32363545/3343043 */
|
||||
.rst-content .hidden-section {
|
||||
display: none;
|
||||
}
|
||||
|
||||
nav .hidden-section {
|
||||
display: inherit;
|
||||
}
|
||||
|
||||
.wy-side-nav-search>div.version {
|
||||
color: #000;
|
||||
}
|
||||
Vendored
+5
File diff suppressed because one or more lines are too long
@@ -0,0 +1,141 @@
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
log = logging.getLogger(os.path.basename(__file__))
|
||||
|
||||
|
||||
def module_template(module_qualname: str):
|
||||
module_name = module_qualname.split(".")[-1]
|
||||
title = module_name.replace("_", r"\_")
|
||||
return f"""{title}
|
||||
{"=" * len(title)}
|
||||
|
||||
.. automodule:: {module_qualname}
|
||||
:members:
|
||||
:undoc-members:
|
||||
"""
|
||||
|
||||
|
||||
def index_template(package_name: str, doc_references: list[str] | None = None, text_prefix=""):
|
||||
doc_references = doc_references or ""
|
||||
if doc_references:
|
||||
doc_references = "\n" + "\n".join(f"* :doc:`{ref}`" for ref in doc_references) + "\n"
|
||||
|
||||
dirname = package_name.split(".")[-1]
|
||||
title = dirname.replace("_", r"\_")
|
||||
if title == "serena":
|
||||
title = "serena API Reference"
|
||||
return f"{title}\n{'=' * len(title)}" + text_prefix + doc_references
|
||||
|
||||
|
||||
def write_to_file(content: str, path: str):
|
||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||
with open(path, "w") as f:
|
||||
f.write(content)
|
||||
os.chmod(path, 0o666)
|
||||
|
||||
|
||||
_SUBTITLE = (
|
||||
"\n Here is the autogenerated documentation of the serena API. \n \n "
|
||||
"The Table of Contents to the left has the same structure as the "
|
||||
"repository's package code. The links at each page point to the submodules and subpackages. \n\n "
|
||||
"Enjoy scrolling through! \n"
|
||||
)
|
||||
|
||||
|
||||
def make_rst(src_root, rst_root, clean=False, overwrite=False, package_prefix=""):
|
||||
"""Creates/updates documentation in form of rst files for modules and packages.
|
||||
|
||||
Does not delete any existing rst files. Thus, rst files for packages or modules that have been removed or renamed
|
||||
should be deleted by hand.
|
||||
|
||||
This method should be executed from the project's top-level directory
|
||||
|
||||
:param src_root: path to library base directory, typically "src/<library_name>"
|
||||
:param clean: whether to completely clean the target directory beforehand, removing any existing .rst files
|
||||
:param overwrite: whether to overwrite existing rst files. This should be used with caution as it will delete
|
||||
all manual changes to documentation files
|
||||
:package_prefix: a prefix to prepend to each module (for the case where the src_root is not the base package),
|
||||
which, if not empty, should end with a "."
|
||||
:return:
|
||||
"""
|
||||
rst_root = os.path.abspath(rst_root)
|
||||
|
||||
if clean and os.path.isdir(rst_root):
|
||||
shutil.rmtree(rst_root)
|
||||
|
||||
base_package_name = package_prefix + os.path.basename(src_root)
|
||||
|
||||
# TODO: reduce duplication with same logic for subpackages below
|
||||
files_in_dir = os.listdir(src_root)
|
||||
module_names = [f[:-3] for f in files_in_dir if f.endswith(".py") and not f.startswith("_")]
|
||||
subdir_refs = [f"{f}/index" for f in files_in_dir if os.path.isdir(os.path.join(src_root, f)) and not f.startswith("_")]
|
||||
package_index_rst_path = os.path.join(
|
||||
rst_root,
|
||||
"index.rst",
|
||||
)
|
||||
log.info(f"Writing {package_index_rst_path}")
|
||||
write_to_file(
|
||||
index_template(
|
||||
base_package_name,
|
||||
doc_references=module_names + subdir_refs,
|
||||
text_prefix=_SUBTITLE,
|
||||
),
|
||||
package_index_rst_path,
|
||||
)
|
||||
|
||||
for root, dirnames, filenames in os.walk(src_root):
|
||||
if os.path.basename(root).startswith("_"):
|
||||
continue
|
||||
base_package_relpath = os.path.relpath(root, start=src_root)
|
||||
base_package_qualname = package_prefix + os.path.relpath(
|
||||
root,
|
||||
start=os.path.dirname(src_root),
|
||||
).replace(os.path.sep, ".")
|
||||
|
||||
for dirname in dirnames:
|
||||
if dirname.startswith("_"):
|
||||
log.debug(f"Skipping {dirname}")
|
||||
continue
|
||||
files_in_dir = os.listdir(os.path.join(root, dirname))
|
||||
module_names = [f[:-3] for f in files_in_dir if f.endswith(".py") and not f.startswith("_")]
|
||||
subdir_refs = [f"{f}/index" for f in files_in_dir if os.path.isdir(os.path.join(root, dirname, f)) and not f.startswith("_")]
|
||||
if not module_names:
|
||||
log.debug(f"Skipping {dirname} as it does not contain any .py files")
|
||||
continue
|
||||
package_qualname = f"{base_package_qualname}.{dirname}"
|
||||
package_index_rst_path = os.path.join(
|
||||
rst_root,
|
||||
base_package_relpath,
|
||||
dirname,
|
||||
"index.rst",
|
||||
)
|
||||
log.info(f"Writing {package_index_rst_path}")
|
||||
write_to_file(
|
||||
index_template(package_qualname, doc_references=module_names + subdir_refs),
|
||||
package_index_rst_path,
|
||||
)
|
||||
|
||||
for filename in filenames:
|
||||
base_name, ext = os.path.splitext(filename)
|
||||
if ext == ".py" and not filename.startswith("_"):
|
||||
module_qualname = f"{base_package_qualname}.{filename[:-3]}"
|
||||
|
||||
module_rst_path = os.path.join(rst_root, base_package_relpath, f"{base_name}.rst")
|
||||
if os.path.exists(module_rst_path) and not overwrite:
|
||||
log.debug(f"{module_rst_path} already exists, skipping it")
|
||||
|
||||
log.info(f"Writing module documentation to {module_rst_path}")
|
||||
write_to_file(module_template(module_qualname), module_rst_path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
docs_root = Path(__file__).parent
|
||||
make_rst(
|
||||
docs_root / ".." / "src" / "serena",
|
||||
docs_root / "03_api",
|
||||
clean=True,
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"cited": {
|
||||
"01_tutorials/00_example": [
|
||||
"TURING.1950"
|
||||
],
|
||||
"02_notebooks/00_example": [
|
||||
"PlotlyMaps"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# This script provides a platform-independent way of making the jupyter-book call (used in pyproject.toml)
|
||||
toc_file = Path(__file__).parent / "_toc.yml"
|
||||
cmd = f"jupyter-book toc from-project docs -e .rst -e .md -e .ipynb >{toc_file}"
|
||||
print(cmd)
|
||||
os.system(cmd)
|
||||
@@ -0,0 +1,15 @@
|
||||
Welcome to serena!
|
||||
=========================================
|
||||
|
||||
Welcome to the serena library.
|
||||
See the project's repository_ for more information.
|
||||
|
||||
.. _repository: https://github.com/oraios/serena
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
@@ -0,0 +1,11 @@
|
||||
"""Implements a platform-independent way of calling nbstripout (used in pyproject.toml)."""
|
||||
|
||||
import glob
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
if __name__ == "__main__":
|
||||
docs_dir = Path(__file__).parent
|
||||
for path in glob.glob(str(docs_dir / "02_notebooks" / "*.ipynb")):
|
||||
cmd = f"nbstripout {path}"
|
||||
os.system(cmd)
|
||||
@@ -0,0 +1,21 @@
|
||||
@article{TURING.1950,
|
||||
author = {TURING, A. M.},
|
||||
year = {1950},
|
||||
title = {I.---COMPUTING MACHINERY AND INTELLIGENCE},
|
||||
pages = {433--460},
|
||||
volume = {LIX},
|
||||
number = {236},
|
||||
issn = {0026-4423},
|
||||
journal = {Mind},
|
||||
doi = {10.1093/mind/LIX.236.433},
|
||||
file = {ICOMPUTING MACHINERY AND INTELLIGENCE:Attachments/ICOMPUTING MACHINERY AND INTELLIGENCE.pdf:application/pdf}
|
||||
}
|
||||
|
||||
|
||||
@misc{PlotlyMaps,
|
||||
abstract = {Plotly's},
|
||||
year = {2/16/2024},
|
||||
title = {Maps},
|
||||
url = {https://plotly.com/python/maps/},
|
||||
urldate = {2/28/2024}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
serena
|
||||
serena
|
||||
Oraios AI
|
||||
oraios
|
||||
|
||||
appliedAI
|
||||
autogenerated
|
||||
colab
|
||||
docstring
|
||||
docstrings
|
||||
Github
|
||||
html
|
||||
init
|
||||
javascript
|
||||
pre
|
||||
pycharm
|
||||
pydocstyle
|
||||
submodules
|
||||
subpackages
|
||||
utils
|
||||
webpage
|
||||
+254
@@ -0,0 +1,254 @@
|
||||
[build-system]
|
||||
build-backend = "hatchling.build"
|
||||
requires = [
|
||||
"hatchling"
|
||||
]
|
||||
|
||||
[project]
|
||||
name = "serena"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = [
|
||||
{name = "Oraios AI", email = "michael.panchenko@oraios-ai.de"}
|
||||
]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11, <3.12"
|
||||
classifiers = [
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Programming Language :: Python :: 3.11"
|
||||
]
|
||||
dependencies = [
|
||||
"pandas>=2.2.1",
|
||||
"plotly>=5.19.0"
|
||||
]
|
||||
|
||||
[project.license]
|
||||
text = "MIT"
|
||||
|
||||
[project.optional-dependencies]
|
||||
dev = [
|
||||
"black[jupyter]>=23.7.0",
|
||||
"docutils>=0.20.1",
|
||||
"jinja2",
|
||||
"jupyter>=1.0.0",
|
||||
"jupyter-book>=1.0.0",
|
||||
"mypy>=1.4.1",
|
||||
"nbqa>=1.7.1",
|
||||
"nbstripout>=0.6.1",
|
||||
"poethepoet>=0.20.0",
|
||||
"pre-commit>=3.3.3",
|
||||
"pytest>=8.0.2",
|
||||
"pytest-cov",
|
||||
"pytest-lazy-fixtures>=1.0.5",
|
||||
"ruff>=0.0.285",
|
||||
"sphinx>=7",
|
||||
"sphinx-book-theme>=1.0.1",
|
||||
"sphinx-comments>=0.0.3",
|
||||
"sphinx-copybutton>=0.5.2",
|
||||
"sphinx-jupyterbook-latex>=1.0.0",
|
||||
"toml-sort>=0.24.2",
|
||||
"sphinx-togglebutton>=0.3.2",
|
||||
"sphinx-toolbox>=3.5.0",
|
||||
"sphinxcontrib-bibtex",
|
||||
"sphinxcontrib-spelling>=8.0.0",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/oraios/serena"
|
||||
|
||||
[tool.black]
|
||||
line-length = 140
|
||||
target-version = [
|
||||
"py311"
|
||||
]
|
||||
|
||||
[tool.doc8]
|
||||
max-line-length = 1000
|
||||
|
||||
[tool.mypy]
|
||||
allow_redefinition = true
|
||||
check_untyped_defs = true
|
||||
disallow_incomplete_defs = true
|
||||
disallow_untyped_defs = true
|
||||
ignore_missing_imports = true
|
||||
no_implicit_optional = true
|
||||
pretty = true
|
||||
show_error_codes = true
|
||||
show_error_context = true
|
||||
show_traceback = true
|
||||
strict_equality = true
|
||||
strict_optional = true
|
||||
warn_no_return = true
|
||||
warn_redundant_casts = true
|
||||
warn_unreachable = true
|
||||
warn_unused_configs = true
|
||||
warn_unused_ignores = true
|
||||
exclude = "^build/|^docs/"
|
||||
|
||||
[tool.nbqa.exclude]
|
||||
ruff = "\\.jupyter_cache|jupyter_execute"
|
||||
mypy = "\\.jupyter_cache|jupyter_execute"
|
||||
|
||||
[tool.poe.env]
|
||||
PYDEVD_DISABLE_FILE_VALIDATION = "1"
|
||||
|
||||
[tool.poe.tasks]
|
||||
test = "pytest test --cov=serena --cov-report=xml --cov-report=term-missing --durations=0 -v --color=yes"
|
||||
_black_check = "black --check ."
|
||||
_ruff_check = "ruff check ."
|
||||
_ruff_check_nb = "nbqa ruff check docs"
|
||||
_black_format = "black ."
|
||||
_ruff_format = "ruff check --fix ."
|
||||
_ruff_format_nb = "nbqa ruff --fix docs"
|
||||
lint = [
|
||||
"_black_check",
|
||||
"_ruff_check",
|
||||
"_ruff_check_nb"
|
||||
]
|
||||
clean-nbs = "python docs/nbstripout.py"
|
||||
format = [
|
||||
"_ruff_format",
|
||||
"_ruff_format_nb",
|
||||
"_black_format"
|
||||
]
|
||||
_autogen_rst = "python docs/autogen_rst.py"
|
||||
_sphinx_build = "sphinx-build -W -b html docs docs/_build"
|
||||
_jb_generate_toc = "python docs/create_toc.py"
|
||||
_jb_generate_config = "jupyter-book config sphinx docs/"
|
||||
doc-clean = "rm -rf docs/_build"
|
||||
doc-generate-files = [
|
||||
"_autogen_rst",
|
||||
"_jb_generate_toc",
|
||||
"_jb_generate_config"
|
||||
]
|
||||
doc-spellcheck = "sphinx-build -W -b spelling docs docs/_build"
|
||||
doc-build = [
|
||||
"doc-generate-files",
|
||||
"doc-spellcheck",
|
||||
"_sphinx_build"
|
||||
]
|
||||
_mypy = "mypy src"
|
||||
_mypy_nb = "nbqa mypy docs"
|
||||
type-check = [
|
||||
"_mypy",
|
||||
"_mypy_nb"
|
||||
]
|
||||
|
||||
[tool.ruff]
|
||||
target-version = "py311"
|
||||
line-length = 140
|
||||
|
||||
[tool.ruff.format]
|
||||
quote-style = "double"
|
||||
indent-style = "space"
|
||||
line-ending = "auto"
|
||||
skip-magic-trailing-comma = false
|
||||
docstring-code-format = true
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = [
|
||||
"ASYNC",
|
||||
"B",
|
||||
"C4",
|
||||
"C90",
|
||||
"COM",
|
||||
"D",
|
||||
"DTZ",
|
||||
"E",
|
||||
"F",
|
||||
"FLY",
|
||||
"G",
|
||||
"I",
|
||||
"ISC",
|
||||
"PIE",
|
||||
"PLC",
|
||||
"PLE",
|
||||
"PLW",
|
||||
"RET",
|
||||
"RUF",
|
||||
"RSE",
|
||||
"SIM",
|
||||
"TID",
|
||||
"UP",
|
||||
"W",
|
||||
"YTT"
|
||||
]
|
||||
ignore = [
|
||||
"RUF002",
|
||||
"RUF005",
|
||||
"SIM118",
|
||||
"SIM108",
|
||||
"E501",
|
||||
"E741",
|
||||
"B008",
|
||||
"B011",
|
||||
"B028",
|
||||
"D100",
|
||||
"D101",
|
||||
"D102",
|
||||
"D103",
|
||||
"D104",
|
||||
"D105",
|
||||
"D107",
|
||||
"D200",
|
||||
"D203",
|
||||
"D213",
|
||||
"D401",
|
||||
"D402",
|
||||
"DTZ005",
|
||||
"E402",
|
||||
"E501",
|
||||
"E701",
|
||||
"E731",
|
||||
"C408",
|
||||
"E203",
|
||||
"G004",
|
||||
"RET505",
|
||||
"D106",
|
||||
"D205",
|
||||
"D212",
|
||||
"PLW2901",
|
||||
"B027",
|
||||
"D404",
|
||||
"D407",
|
||||
"D408",
|
||||
"D409",
|
||||
"D400",
|
||||
"D415",
|
||||
"COM812",
|
||||
"RET503",
|
||||
"RET504",
|
||||
"UP038",
|
||||
"F403",
|
||||
"F405",
|
||||
"C401",
|
||||
"C901"
|
||||
]
|
||||
unfixable = [
|
||||
"F841",
|
||||
"F601",
|
||||
"F602",
|
||||
"B018"
|
||||
]
|
||||
extend-fixable = [
|
||||
"F401",
|
||||
"B905",
|
||||
"W291"
|
||||
]
|
||||
|
||||
[tool.ruff.lint.mccabe]
|
||||
max-complexity = 20
|
||||
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
"tests/**" = [
|
||||
"D103"
|
||||
]
|
||||
"docs/**" = [
|
||||
"D103"
|
||||
]
|
||||
"examples/**" = [
|
||||
"D103"
|
||||
]
|
||||
"scripts/**" = [
|
||||
"D103"
|
||||
]
|
||||
@@ -0,0 +1,5 @@
|
||||
from serena.sample_module import SampleClass
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(SampleClass().sample_method("Oraios AI"))
|
||||
print("Your new library project serena is waiting for you!")
|
||||
@@ -0,0 +1 @@
|
||||
__version__ = "0.1.0-dev1"
|
||||
@@ -0,0 +1,25 @@
|
||||
"""Top-level module."""
|
||||
|
||||
|
||||
class SampleClass:
|
||||
"""Sample docstring. Note that init docstrings should be underneath the class and not the init method itself
|
||||
(this looks prettier in sphinx). They still will be rendered correctly in pycharm's quick documentation.
|
||||
|
||||
:param param: some parameter
|
||||
"""
|
||||
|
||||
def __init__(self, param: str | None = None):
|
||||
self.hello = "hello "
|
||||
self.param = param
|
||||
|
||||
def sample_method(self, name: str) -> str:
|
||||
""">>> from serena.sample_module import SampleClass
|
||||
>>>
|
||||
>>> greeter = SampleClass()
|
||||
>>> greeter.sample_method("Oraios AI")
|
||||
'hello Oraios AI'.
|
||||
|
||||
:param name:
|
||||
:return:
|
||||
"""
|
||||
return self.hello + name
|
||||
@@ -0,0 +1,6 @@
|
||||
"""Module in a separate package."""
|
||||
|
||||
|
||||
def hello_stranger() -> None:
|
||||
"""Hello."""
|
||||
print("Hello from a separate package!")
|
||||
@@ -0,0 +1,11 @@
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def fixture_1():
|
||||
return 1
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def fixture_2():
|
||||
return 2
|
||||
@@ -0,0 +1,17 @@
|
||||
# Here we demonstrate a convenient pytest plugin called lazy fixture.
|
||||
# It allows to use fixtures within test parametrization, which is especially useful
|
||||
# if you want to test the method on different input data. Unfortunately, this forces one to use string
|
||||
# interfaces for fixture but this is a price one might be willing to pay.
|
||||
import pytest
|
||||
from pytest_lazy_fixtures import lf
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"fixture, result",
|
||||
[
|
||||
(lf("fixture_1"), 1),
|
||||
(lf("fixture_2"), 2),
|
||||
],
|
||||
)
|
||||
def test_demonstrateLazyFixture(fixture, result):
|
||||
assert fixture == result
|
||||
@@ -0,0 +1,8 @@
|
||||
from serena.sample_module import SampleClass
|
||||
|
||||
|
||||
# the suggested naming convention for unit tests is test_method_name_testDescriptionInCamelCase
|
||||
# this leads to a nicely readable output of pytest
|
||||
def test_sample_class_attributes_greeterSaysHello():
|
||||
greeter = SampleClass()
|
||||
assert greeter.hello == "hello "
|
||||
Reference in New Issue
Block a user