Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
PEP 517 doesnt support editable installs
PEP 517 doesn't support editable installs
so this file is currently here to support "pip install -e ."
"""
""" # noqa: RUF002
from setuptools import setup

setup(
Expand Down
6 changes: 5 additions & 1 deletion src/starfile/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
from .functions import read, write, to_string
"""STAR file format reader and writer."""

from .functions import read, to_string, write

__all__ = ["read", "write", "to_string"]
44 changes: 25 additions & 19 deletions src/starfile/__main__.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,41 @@
"""Command-line interface for STAR file reading and inspection."""

try:
from IPython.terminal.embed import InteractiveShellEmbed
import click
from IPython.terminal.embed import InteractiveShellEmbed
except ImportError:
deps = False
else:
deps = True


if deps:
@click.command()
@click.argument('path', type=click.Path(exists=True, dir_okay=False, readable=True))
@click.option('--read_n_blocks', type=int)
@click.option('--always_dict', is_flag=True)
def cli(path, read_n_blocks, always_dict):
"""
Read a star file and open an ipython console to interactively inspect its contents
"""
# imports here will be available in the embedded shell
from .functions import read, write

star = read(path, read_n_blocks, always_dict)
@click.command() # type: ignore[misc]
@click.argument("path", type=click.Path(exists=True, dir_okay=False, readable=True)) # type: ignore[misc]
@click.option("--read_n_blocks", type=int) # type: ignore[misc]
@click.option("--always_dict", is_flag=True) # type: ignore[misc]
def cli(path: str, read_n_blocks: int | None, always_dict: bool) -> None:
"""Read a star file and open an ipython console to inspect contents."""
from pathlib import Path

banner = '''=== Starfile ===
- access your data with `star`
from .functions import read

_ = read(Path(path), read_n_blocks, always_dict)

banner = """=== Starfile ===
- access your data with `data`
- write it out with `write(...)`
- read more with `read(...)`
'''
# sh.instance() needed due to reggression in ipython
# https://github.com/ipython/ipython/issues/13966#issuecomment-1696137868
"""
sh = InteractiveShellEmbed.instance(banner2=banner)
sh()

else:
def cli():
print('To use the command line utility, install with `pip install starfile[cli]`')

def cli() -> None:
"""Print installation instructions."""
print(
"To use the command line utility, install with "
"`pip install starfile[cli]`"
)
54 changes: 27 additions & 27 deletions src/starfile/functions.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
"""High-level interface for reading and writing STAR files."""
from __future__ import annotations

from typing import TYPE_CHECKING, Dict, List, Union, Optional
from typing import TYPE_CHECKING

if TYPE_CHECKING:
import pandas as pd
from os import PathLike

from .typing import DataBlock

from .parser import StarParser
from .writer import StarWriter
from .typing import DataBlock

if TYPE_CHECKING:
import pandas as pd
from os import PathLike


def read(
filename: PathLike,
read_n_blocks: Optional[int] = None,
read_n_blocks: int | None = None,
always_dict: bool = False,
parse_as_string: List[str] = []
) -> Union[DataBlock, Dict[DataBlock]]:
parse_as_string: list[str] | None = None,
) -> DataBlock | dict[str, DataBlock]:
"""Read data from a STAR file.

Basic data blocks are read as dictionaries. Loop blocks are read as pandas
dataframes. When multiple data blocks are present a dictionary of datablocks is
returned. When a single datablock is present only the block is returned by default.
To force returning a dectionary even when only one datablock is present set
To force returning a dictionary even when only one datablock is present set
`always_dict=True`.

Parameters
Expand All @@ -40,23 +37,26 @@ def read(
parse_as_string: list[str]
A list of keys or column names which will not be coerced to numeric values.
"""
parser = StarParser(filename, n_blocks_to_read=read_n_blocks, parse_as_string=parse_as_string)
if parse_as_string is None:
parse_as_string = []
parser = StarParser(
filename, n_blocks_to_read=read_n_blocks, parse_as_string=parse_as_string
)
if len(parser.data_blocks) == 1 and always_dict is False:
return list(parser.data_blocks.values())[0]
else:
return parser.data_blocks
return next(iter(parser.data_blocks.values()))
return parser.data_blocks


def write(
data: Union[DataBlock, Dict[str, DataBlock], List[DataBlock]],
data: DataBlock | dict[str, DataBlock] | list[DataBlock],
filename: PathLike,
float_format: str = '%.6f',
sep: str = '\t',
na_rep: str = '<NA>',
float_format: str = "%.6f",
sep: str = "\t",
na_rep: str = "<NA>",
quote_character: str = '"',
quote_all_strings: bool = False,
**kwargs
):
**kwargs: object,
) -> None:
"""Write data to disk in the STAR format.

Parameters
Expand Down Expand Up @@ -85,14 +85,14 @@ def write(


def to_string(
data: Union[DataBlock, Dict[str, DataBlock], List[DataBlock]],
float_format: str = '%.6f',
sep: str = '\t',
na_rep: str = '<NA>',
data: DataBlock | dict[str, DataBlock] | list[DataBlock],
float_format: str = "%.6f",
sep: str = "\t",
na_rep: str = "<NA>",
quote_character: str = '"',
quote_all_strings: bool = False,
**kwargs
):
**kwargs: object,
) -> str:
"""Represent data in the STAR format.

Parameters
Expand Down
Loading