votable-cli


Namevotable-cli JSON
Version 0.6.1 PyPI version JSON
download
home_pagehttps://github.com/cds-astro/cds-votable-rust/tree/main/crates/cli
SummaryCommand-line to extract/edit metadata from IVOA VOTables and to convert efficiently VOTable back and forth in XML-TABLEDATA, XML-BINARY, XML-BINARY2, non-standard JSON/YAML/TOML (and to CSV).
upload_time2024-04-15 14:51:46
maintainerNone
docs_urlNone
authorF.-X. Pineau <francois-xavier.pineau@astro.unistra.fr>
requires_pythonNone
licenseMIT OR Apache-2.0
keywords ivoa votable xml
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <meta charset="utf-8"/>

# `votable-cli` or `VOTCli`

Command-line to extract/edit metadata from [IVOA VOTables](https://www.ivoa.net/documents/VOTable/20191021/REC-VOTable-1.4-20191021.html)
and to convert efficiently VOTables back and forth in XML-TABLEDATA, XML-BINARY, XML-BINARY2, non-standard JSON/YAML/TOML and to CSV.

## Status

The CLI is in active development.

More testing is required, especially for the bit type and arrays.
Please, provide us with VOTable examples and/or usecases!

 
## Install

### From pypi for python users

VOTable cli is available in [pypi](https://pypi.org/project/votable-cli/),
you can thus install the `vot` executable using `pip`:
```bash
pip install votable-cli
vot --help
```

### Debian package

Download the last `votable-cli_vxx_yyy.deb` corresponding to your architecture
(`x86_64_musl` has the most chances to fit your needs)
from the [github release page](https://github.com/cds-astro/cds-votable-rust/releases).

Install the `.deb` by clicking on it or using the command line:
```bash
sudo dpkg -i votable-cli_vxx_yyy.deb
sudo apt-get install -f
```

Then you can use the tool:
```bash
vot
man vot
```

You can uninstall using, e.g.:
```bash
sudo dpkg -r $(dpkg -f votable-cli_vxx_yyy.deb Package)
```

### Pre-compile binaries for MacOS, Linux and Windows

Download the last `vot-vxx_yyy.tar.gz` corresponding to your architecture
from the [github release page](https://github.com/cds-astro/cds-votable-rust/releases).
You probably want ot use:
* Linux: `vot-vxx-x86_64-unknown-linux-musl.tar.gz`
* MacOS: `vot-vxx-x86_64-apple-darwin.tar.gz`
* Windows: `vot-vxx-.zip`

WARNING: for linux, use [`musl`](https://en.wikipedia.org/wiki/Musl) instead of `gnu` (high chances of uncompatibility in the latter case)

The tar contains a single executable binary file.
```bash
tar xzvf vot-vxx-yyy.tar.gz
./vot
```


### Compile from source code

[Install rust](https://www.rust-lang.org/tools/install)
(and check that `~/.cargo/bin/` is in your path),
or update the Rust compiler with:
```bash
rustup update
``` 

Clone the [votable lib rust](https://github.com/cds-astro/cds-votable-rust) project:
```bash
git clone https://github.com/cds-astro/cds-votable-rust
```
Install from using `cargo`:
```bash
cargo install --all-features --path crates/cli
```


## Check 'vot' tool version

Once installed, check the version number using:
```
> vot --version
votable-cli 0.6.1
```


## Help messages

```bash
> vot --help
Command-line to extract/edit metadata from IVOA VOTables and to convert efficiently VOTable back and forth in XML-TABLEDATA, XML-BINARY, XML-BINARY2, non-standard JSON/YAML/TOML (and to CSV).

Usage: vot <COMMAND>

Commands:
  convert   Convert a VOTable from one format to another (full table loaded in memory)
  sconvert  Convert a single table XML VOTable in streaming mode
  edit      Edit metadata adding/removing/updating attributes and/or elements
  get       Get information from a VOTable: e.g. its structure or fields metadata
  help      Print this message or the help of the given subcommand(s)

Options:
  -h, --help     Print help
  -V, --version  Print version
```

```bash
> vot convert --help
Convert a VOTable from one format to another (full table loaded in memory)

Usage: vot convert [OPTIONS] --out-fmt <OUTPUT_FMT>

Options:
  -i, --in <FILE>             Path of the input VOTable [default: read from stdin]
  -t, --in-fmt <INPUT_FMT>    Format of the input VOTable (standard: 'xml'; not standard: 'json', 'yaml' or 'toml') [default: guess from file extension]
  -o, --out <FILE>            Path of the output VOTable [default: write to stdout]
  -f, --out-fmt <OUTPUT_FMT>  Format of the output VOTable (standard: 'xml', 'xml-td', 'xml-bin', 'xml-bin2'; not standard: 'json', 'yaml', 'toml')
  -p, --pretty                Pretty print (for JSON and TOML)
  -h, --help                  Print help
```

```bash
> vot sconvert --help
Convert a single table XML VOTable in streaming mode

Usage: vot sconvert [OPTIONS] --out-fmt <OUTPUT_FMT>

Options:
  -i, --in <FILE>                Path of the input XML VOTable [default: read from stdin]
  -o, --out <FILE>               Path of the output file [default: write to stdout]
  -f, --out-fmt <OUTPUT_FMT>     Format of the output file ('xml-td', 'xml-bin', 'xml-bin2' or 'csv')
  -s, --separator <SEPARATOR>    Separator used for the 'csv' format [default: ,]
      --parallel <N>             Exec concurrently using N threads
      --chunk-size <CHUNK_SIZE>  Number of rows process by a same thread in `parallel` mode [default: 10000]
  -h, --help                     Print help
```

```bash
> vot get --help
Get information from a VOTable: e.g. its structure or fields metadata

Usage: vot get [OPTIONS] <COMMAND>

Commands:
  struct        Print the VOTable structure: useful to get Virtual IDs used in edition
  colnames      Print column names, one line per table.
  fields-array  Print selected field information as an array
  help          Print this message or the help of the given subcommand(s)

Options:
  -i, --in <FILE>           Path of the input VOTable [default: read from stdin]
  -t, --in-fmt <INPUT_FMT>  Format of the input VOTable (standard: 'xml'; not standard: 'json', 'yaml' or 'toml') [default: guess from file extension]
  -s, --early-stop          Stop parsing before reading first data ('xml' input only): useful for large single-table files
  -h, --help                Print help
```

```bash
> vot edit --help
Edit metadata adding/removing/updating attributes and/or elements

Usage: vot edit [OPTIONS] --out-fmt <OUTPUT_FMT>

Options:
  -i, --in <FILE>             Path of the input VOTable [default: read from stdin]
  -t, --in-fmt <INPUT_FMT>    Format of the input VOTable (standard: 'xml'; not standard: 'json', 'yaml' or 'toml') [default: guess from file extension]
  -o, --out <FILE>            Path of the output VOTable [default: write to stdout]
  -f, --out-fmt <OUTPUT_FMT>  Format of the output VOTable (standard: 'xml', 'xml-td', 'xml-bin', 'xml-bin2'; not standard: 'json', 'yaml', 'toml')
  -p, --pretty                Pretty print (for JSON and TOML)
  -e, --edit <ELEMS>          List of "TAG CONDITION ACTION ARGS", e.g.:
                              -e 'INFO name=Target rm' -e 'FIELD ID=RA set_attrs ucd=pos.eq.ra;meta.main unit=deg'
                              CONDITIONS:
                                name=VAL  name (if any) equals a given value
                                  id=VAL  id (if any) equals a given value
                                 vid=VAL  virtual id equals a given value
                              ACTIONS ARGS:
                                rm                                                 Remove the TAG
                                set_attrs        KEY=VAL (KEY=VAL) ...               Set TAG attributes
                                set_content      CONTENT                             Set the content for `DESCRIPTION`, `INFO`, `LINK`, `PARAMRef` or `FIELDRef`
                                set_desc         DESC                                Set the `DESCRIPTION` for `VOTABLE`, `RESOURCE`, `TABLE`, `FIELD`, `PARAM` or `GROUP`
                                push_timesys     KEY=VAL (KEY=VAL) ...               Push a new `TIMESYS` in `VOTABLE` or `RESOURCE`
                                set_min          KEY=VAL (KEY=VAL) ...               Set a new `MIN` for `VALUES`.
                                set_max          KEY=VAL (KEY=VAL) ...               Set a new `MAX` for `VALUES`.
                                push_option      KEY=VAL (KEY=VAL) ... (SUB_ACTIONS) Push the new `OPTION` in `VALUES` or `OPTION`
                                set_values       KEY=VAL (KEY=VAL) ... (SUB_ACTIONS) Set the new `VALUES` for `FIELD` or `PARAM`
                                push_info        KEY=VAL (KEY=VAL) ... (SUB_ACTION)  Push the new `INFO` in `VOTABLE`, `RESOURCE` or `TABLE`.
                                push_post_info   KEY=VAL (KEY=VAL) ... (SUB_ACTION)  Push the new post-`INFO` in `VOTABLE`.
                                push_link        KEY=VAL (KEY=VAL) ... (SUB_ACTION)  Push the new `LINK` in  `RESOURCE`, `TABLE`, `FIELD` or `PARAM`.
                                push_fieldref    KEY=VAL (KEY=VAL) ... (SUB_ACTION)  Push the new `FIELDRef` in `COOSYS` or table-`GROUP`.
                                push_paramref    KEY=VAL (KEY=VAL) ... (SUB_ACTION)  Push the new `PARAMRef` in `COOSYS` or `GROUP`.
                                push_coosys      KEY=VAL (KEY=VAL) ... (SUB_ACTION)  Push the new `COOSYS` in `VOTABLE` or `RESOURCE`.
                                push_group       KEY=VAL (KEY=VAL) ... (SUB_ACTIONS) Push the new `GROUP` in `VOTABLE` or `RESOURCE`.
                                push_tablegroup  KEY=VAL (KEY=VAL) ... (SUB_ACTIONS) Push the new `GROUP` in `TABLE`.
                                push_param       KEY=VAL (KEY=VAL) ... (SUB_ACTIONS) Push the new `PARAM` in `VOTABLE`, `RESOURCE`, `TABLE` or `GROUP`.
                                push_field       KEY=VAL (KEY=VAL) ... (SUB_ACTIONS) Push the new `FIELD` in `TABLE`.
                                prepend_resource KEY=VAL (KEY=VAL) ... (SUB_ACTIONS) Preprend the new `RESOURCE` in `VOTABLE` or `RESOURCE`.
                                push_resource    KEY=VAL (KEY=VAL) ... (SUB_ACTIONS) Push the new `RESOURCE` in `VOTABLE` or `RESOURCE`.
                              SUB ACTIONS:
                                Sub-actions are the same as the ACTIONS (except `rm` which is not allowed).
                                A sub-action stars with a `@`. Actually one can see `@` as an action separator with the
                                main action at the left of the first `@` and all other actions being sub-actions applying on
                                the element created by the main action (the parent element).
                                E.g, in:
                                  `push_param KEY=VAL ... @set_description ... @push_link ...`
                                Both `set_description` an `push_link` are executed on the new `PARAM` built by `push_param`.
                                For sub-actions to be executed on the last created element, you can double once the `@`:
                                  `push_param KEY=VAL ... @set_description ... @push_link ... @@set_content CONTENT`
                                Here `set_content` will be applied on the new `LINK` before pushing it in the new `PARAM`.
                                After a `@@`, all sub-commands are executed on the last created element.
                                To go up from one level in the element hierarchy, use `@<`:
                                  `push_param KEY=VAL ... @set_description ... @push_link ... @@set_content CONTENT @< @push_link ...`
                                You can use arbitrary deeply nested elements using `@@` and `@<`.
                                Those three commands do not lead to the same hierarchy:
                                  `push_group ... @push_group ... @push_group @@push_group @push_group (@<)`
                                  `push_group ... @push_group ... @push_group @@push_group @@push_group (@<@<)`
                                  `push_group ... @push_group ... @push_group @@push_group @< @push_group`
                                Remark: `@@xxx` is a short version of `@> @xxx`.
  -z, --vizier-org-names      Extract original column names from VizieR description ending by '(org_name)' and put it inn the non-standard 'viz:org_name' attribute, be aware of the risk of false-detections!
  -s, --streaming             Use streaming mode: only for large XML files with a single table, and if the input format is the same as the output format
  -h, --help                  Print help
```

## Examples

### XML/JSON/TOML/YAML convertion 

```bash
# In memory conversion of a VOTable from XML-TABLEDATA to JSON
vot convert --in my_votable.xml --out my_votable.json --out-fmt json
```

### Streaming conversion XML-TD, XML-BIN, XML-BIN2 and CSV

```bash
# Streaming conversion of a VOTable from XML-TABLEDATA to XML-BINARY
vot sconvert --in my_votable.xml --out my_votable.xml.b64  --out-fmt xml-bin
# Streaming conversion from XML to CSV, in parallel, of a single large table
vot sconvert --in my_votable.xml --out my_votable.csv --out-fmt csv --parallel 6
```

### Get metadata

```bash
# Get the structure of a VOTable with virtual identifier for each element
vot get --in my_votable.xml struct --line-width 120
# Get the structure of a large VOTable till first DATA tag is reached
vot get --in my_votable.xml --early-stop struct --line-width 120
# Get only the colum names of a large table, with a non-ascii separator
vot get --in my_votable.xml --early-stop colnames --separator '▮'
# Get an array of fields metadata with selected informations
vot get -in my_votable.xml fields-array index,name,datatype,arraysize,width,precision,unit,ucd,description --separator ,
```

See chosen column metadata of [this votable](resource/test_edit.td.xml)
```bash
> vot get --in test_edit.td.xml fields-array name,datatype,arraysize,width,precision,unit,ucd,description
    name    dt  a w p   unit    ucd                          desc                                                                                                                         
   recno   int    8             meta.record                  Record number assigned by the VizieR team. Should Not be used for identification.                                            
  f_GCTP  char  1               meta.code                    [*] Indicates a note in file "errata.dat"                                                                                    
    GCTP float    7 2           meta.id;meta.main            Catalog number                                                                                                               
    comp  char  1               meta.code.multip             Double star component                                                                                                        
  RA1900  char 10      "h:m:s"  pos.eq.ra;meta.main          ?Right ascension hours (1900.0)                                                                                              
  DE1900  char  9      "d:m:s"  pos.eq.dec;meta.main         ?Declination degrees (1900.0)                                                                                                
u_RA1900  char  1               meta.code.error;pos.eq.ra    [:C] : = lower precision position                                                                                            
    Vmag float    5 2    mag    phot.mag;em.opt.V            ?V magnitude or other magnitude                                                                                              
  n_Vmag  char  1               meta.note                    P indicates blue passband                                                                                                    
     B-V float    5 2    mag    phot.color;em.opt.B;em.opt.V ?B-V color                                                                                                                   
     U-B float    5 2    mag    phot.color;em.opt.U;em.opt.B ?U-B color                                                                                                                   
  r_Vmag  char  1               meta.ref;pos.frame           Source code for photometry                                                                                                   
      MK  char  *               src.spType                   Spectral type                                                                                                                
    r_MK  char  1               meta.ref;pos.frame           Source code for spectral type                                                                                                
     var  char  9               meta.id                      Variable star name                                                                                                           
      HR short    4             meta.id                      ?HR number [NULL integer written as an empty string]                                                                         
    supp  char  1               meta.note                    [S] S=in Hoffleit BSS Cat. <V/36>                                                                                            
      HD  char  7               meta.id                      HD number and component                                                                                                      
      DM  char 10               meta.id                      DM identification and component                                                                                              
    name  char  *               meta.id                      Star name                                                                                                                    
      pm float    6 3 arcsec/yr pos.pm                       ?Total Proper motion                                                                                                         
    pmPA short    3      deg    pos.posAng;pos.pm            ?Proper motion position angle [NULL integer written as an empty string]                                                      
      pi float    7 4  arcsec   pos.parallax.trig            ?Weighted absolute parallax                                                                                                  
    e_pi float    4 1    mas    stat.error                   ?Standard error of parallax                                                                                                  
    q_pi  char  1               meta.code.qual               [ GFPX]Quality of interagreement                                                                                             
    o_pi short    2             meta.number                  ?Number of parallax observations [NULL integer written as an empty string]                                                   
  Simbad  char  *               meta.ref.url                 SIMBAD data for this star                                                                                                    
_RA.icrs  char 10      "h:m:s"  pos.eq.ra                    Right ascension (ICRS) at Epoch=J2000, proper motions taken into account  (computed by VizieR, not part of the original data)
_DE.icrs  char  9      "d:m:s"  pos.eq.dec                   Declination (ICRS) at Epoch=J2000, proper motions taken into account  (computed by VizieR, not part of the original data) 
```

See the `structure` (with Virtual IDs) of the previous table:
```bash
> vot get --in test_edit.td.xml struct
VOTABLE vid=D
  RESOURCE vid=DR1
    RESOURCE vid=DR1R1
      COOSYS vid=DR1R1C1 ID=t4-coosys-1 system=eq_FK4 equinox=B1900
    TABLE vid=DR1T1 name=I/238A/picat nrows=8994
      DESCRIPTION vid=DR1T1d content=The data file
      PARAM vid=DR1T1P1 name=votable-version datatype=char value=1.99+ (14-Oct-2013) arraysize=19
      PARAM vid=DR1T1P2 name=-ref datatype=char value=VOTx25520 arraysize=9
      PARAM vid=DR1T1P3 name=-out.max datatype=char value=50000 arraysize=5
      PARAM vid=DR1T1P4 name=queryParameters datatype=char value=4 arraysize=1
        DESCRIPTION vid=DR1T1P4d content=-oc.form=dec\n-source=I/238A\n-out.all\n-out.max=50000
      FIELD vid=DR1T1F1 name=recno datatype=int width=8 ucd=meta.record
        DESCRIPTION vid=DR1T1F1d content=Record number assigned by the VizieR team. Should Not be used for identific...
        LINK vid=DR1T1F1l1 title=LINK
          href=http://vizier.u-strasbg.fr/viz-bin/VizieR-5?-info=XML&-out.add=.&-source=I/238A/picat&recno=${recno}
      ...
```

### Edit

When editing a VOTable, you probably need Virtual IDs (vid) to select tags you want to remove or to modify.
One Virtual ID is attributed by votable-cli to each tag of the VOTable.
To know the vid attributed to each tag, you can use the `vot get ... struct` subcommand. 

In the following example, we modify [this votable](resource/test_edit.td.xml) to:
* remove the first sub-RESOURCE
* add attributes to the main RESOURCE
* add DESCRIPTION to the main RESOURCE
* add COOSYS with FIELDref to the main resource
* remove PARAMs
* add a PARAM
* rename the column `recno` into `RecordNumber` 
* remove a LINK
* add an INFO to the TABLE
* add a post-INFO to the VOTABLE


```bash
# Command used to get the vid (Virtual ID) of each tag in the VOTable
vot get --in test_edit.td.xml struct 

# Command used to rename column 'recno' into 'RecordNumber'
# (the 'streaming' option on such a small table is useless)
vot edit --in test_edit.td.xml --out-fmt xml-td --streaming \
  -e 'FIELD name=recno set_attrs name=RecordNumber'

# Command used to edit the VOTable
# (the 'streaming' option on such a small table is useless)
vot edit --in test_edit.td.xml --out-fmt xml-td --streaming \
  -e 'RESOURCE vid=DR1R1 rm' \
  -e 'RESOURCE vid=DR1 set_attrs ID=R1 name=main_resource' \
  -e 'RESOURCE vid=DR1 set_description The main resource containing my super table' \
  -e 'RESOURCE vid=DR1 push_coosys ID=t4-coosys-1 system=eq_FK4 equinox=B1900 
        @push_fieldref ref=RA1900 
	  @@set_content Ref to the RA column @<
        @push_fieldref ref=DE1900 
	  @@set_content Ref to the Declination column @<' \
  -e 'PARAM name=votable-version rm' \
  -e 'PARAM name=-ref rm' \
  -e 'PARAM name=-out.max rm' \
  -e 'PARAM name=queryParameters rm' \
  -e 'TABLE name=I/238A/picat push_param name=hpx_order datatype=unsignedByte value=8 
       @set_description HEALPix order
       @set_values 
         @@set_min value=0  inclusive=true 
	  @set_max value=29 inclusive=true
	 @<
       @push_link href=https://en.wikipedia.org/wiki/HEALPix
         @@set_content General HEALPix info on Wikipedia @<' \
  -e 'FIELD name=recno set_attrs name=RecordNumber' \
  -e 'LINK vid=DR1T1F27l1 rm' \
  -e 'TABLE name=I/238A/picat push_info name=ps value=my post-scriptum @set_content My super post-scriptum' \
  -e 'VOTABLE vid=D push_post_info name=warning value=This table has been modified by using vot-cli'
```


## Log messages

You can adapt the `level` of log messages using
the environement variable `RUST_LOG` with one of the following value:
`error`, `warn`, `info`, `debug`, `trace` and `off`.

E.g.:
```bash
RUST_LOG="trace" vot get --in my_votable.xml struct
```

See [env_logger](https://docs.rs/env_logger/latest/env_logger/) for more details.


## Performances

To convert large tables, use the `sconvert` sub-command with the `--parallel` option.

WARNING: so far, the `--parallel` option does not preserve the rows order, 
let me know if it is problematic.

Test on my computer:
* Intel(R) Core(TM) i5-6600 (4 cores, 4 threads)
* NVMe SSD

Input file: `gaia_dr3.vot`
* 2.8 GB
* 225 columns
* 999999 rows

```bash
# Convert from TABLEDATA to BINARY
time vot sconvert --in gaia_dr3.vot --out out.bin.vot --out-fmt xml-bin --parallel 3

real	0m15,339s
user	0m40,220s
sys	0m2,273s


# Convert from TABLEDATA to BINARY2
time vot sconvert --in gaia_dr3.vot --out out.bin2.vot --out-fmt xml-bin2 --parallel 3

real	0m17,157s
user	0m43,255s
sys	0m2,297s


# Convert from TABLEDATA to CSV
time vot sconvert --in gaia_dr3.vot --out out.csv --out-fmt csv --parallel 3

real	0m11,392s
user	0m33,875s
sys	0m1,413s


# Convert from TABLEDATA to CSV
time vot sconvert --in out.bin.vot --out out.csv --out-fmt csv --parallel 3

real	0m18,903s
user	0m32,819s
sys	0m1,833s
```

With `out.bin.vot` and `out.bin2.vot` about 1.5 and 1.6 GB respectively, 
and `out.csv` about 1.1 and 0.99 GB respectively.


Same test on a fast server (lot of CPUs, NVMe RAID) with 20 threads:
```
# Convert from TABLEDATA to BINARY
time vot sconvert --in gaia_dr3.vot --out out.bin.vot --out-fmt xml-bin --parallel 20

real	0m5,123s
user	1m6,248s
sys	0m4,619s


# Convert from TABLEDATA to BINARY2
time vot sconvert --in gaia_dr3.vot --out out.bin2.vot --out-fmt xml-bin2 --parallel 20

real	0m5,465s
user	1m9,436s
sys	0m4,106s


# Convert from TABLEDATA to CSV
time vot sconvert --in gaia_dr3.vot --out out.csv --out-fmt csv --parallel 20

real	0m4,539s
user	0m53,226s
sys	0m3,574s


# Convert from TABLEDATA to CSV
time vot sconvert --in out.bin.vot --out out.csv --out-fmt csv --parallel 20

real	0m12,416s
user	0m47,123s
sys	0m2,302s
```

## Similar tool

(Please let me known if you want me to add another tool here!) 

### Astropy

Not really a CLI tool, but you can write python scripts (and thus probably do anything you want)
using the [astropy.io.votable](https://docs.astropy.org/en/stable/io/votable/index.html) package.
So far, the main limitations seems to be related to [large files](https://github.com/astropy/astropy/issues/14577)
and performances (?).


### STILTS

The main other CLI tool I am aware of to convert between possibly large 
XML-TABLEDATA/XML-BINARY/XML-BINARY2 (and to CSV) is 
[stilts](https://www.star.bris.ac.uk/~mbt/stilts/) with the 
[votcopy](https://www.star.bristol.ac.uk/mbt/stilts/sun256/votcopy-usage.html) command.

Stilts also allows for metadata edition, see [tpipe](https://www.star.bris.ac.uk/~mbt/stilts/sun256/tpipe-usage.html)
command with [colmeta](https://www.star.bris.ac.uk/~mbt/stilts/sun256/colmeta.html) or [setparam](https://www.star.bris.ac.uk/~mbt/stilts/sun256/setparam.html) 
[procesing filter](https://www.star.bris.ac.uk/~mbt/stilts/sun256/filterSteps.html), but:
* if data/metadata editing is required, VOTable structure may change
* editing of VOTable-specific metadata is not always possible

Stilts is a very general, rich, efficient and robust tool with a lot of options to be explored.

Regarding performances, the single threaded version of `vot-cli` shows performances similar to `stilts vocopy`.
The multi-threaded version of `vot sconvert` (i.e. with `--parallel` option) may increase performances up to x10 
depending on the hardware, the VOTable file and the type of conversion.


## To-Do list

* [X] Support `CDATA` in `TD` tags
* [X] Use the iterator to implement streaming transformations between DATATABLE/BINARY/BINARY2.
* [X] Also implement streaming conversion to CSV.
* [X] Add commands to modify a VOTable metadata.
* [ ] Implement streaming mode for multiple tables (if it is really useful, please tell me).
* [ ] Add commands to select/compute columns and filter rows?


## License

Like most projects in Rust, this project is licensed under either of

* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
  http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
  http://opensource.org/licenses/MIT)

at your option.


## Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this project by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.





            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/cds-astro/cds-votable-rust/tree/main/crates/cli",
    "name": "votable-cli",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "ivoa, votable, xml",
    "author": "F.-X. Pineau <francois-xavier.pineau@astro.unistra.fr>",
    "author_email": "F.-X. Pineau <francois-xavier.pineau@astro.unistra.fr>",
    "download_url": "https://files.pythonhosted.org/packages/7c/85/85dcfeee6f08e373080556cbeadc3479a1d3758b273bc221130b519e3b87/votable_cli-0.6.1.tar.gz",
    "platform": null,
    "description": "<meta charset=\"utf-8\"/>\n\n# `votable-cli` or `VOTCli`\n\nCommand-line to extract/edit metadata from [IVOA VOTables](https://www.ivoa.net/documents/VOTable/20191021/REC-VOTable-1.4-20191021.html)\nand to convert efficiently VOTables back and forth in XML-TABLEDATA, XML-BINARY, XML-BINARY2, non-standard JSON/YAML/TOML and to CSV.\n\n## Status\n\nThe CLI is in active development.\n\nMore testing is required, especially for the bit type and arrays.\nPlease, provide us with VOTable examples and/or usecases!\n\n \n## Install\n\n### From pypi for python users\n\nVOTable cli is available in [pypi](https://pypi.org/project/votable-cli/),\nyou can thus install the `vot` executable using `pip`:\n```bash\npip install votable-cli\nvot --help\n```\n\n### Debian package\n\nDownload the last `votable-cli_vxx_yyy.deb` corresponding to your architecture\n(`x86_64_musl` has the most chances to fit your needs)\nfrom the [github release page](https://github.com/cds-astro/cds-votable-rust/releases).\n\nInstall the `.deb` by clicking on it or using the command line:\n```bash\nsudo dpkg -i votable-cli_vxx_yyy.deb\nsudo apt-get install -f\n```\n\nThen you can use the tool:\n```bash\nvot\nman vot\n```\n\nYou can uninstall using, e.g.:\n```bash\nsudo dpkg -r $(dpkg -f votable-cli_vxx_yyy.deb Package)\n```\n\n### Pre-compile binaries for MacOS, Linux and Windows\n\nDownload the last `vot-vxx_yyy.tar.gz` corresponding to your architecture\nfrom the [github release page](https://github.com/cds-astro/cds-votable-rust/releases).\nYou probably want ot use:\n* Linux: `vot-vxx-x86_64-unknown-linux-musl.tar.gz`\n* MacOS: `vot-vxx-x86_64-apple-darwin.tar.gz`\n* Windows: `vot-vxx-.zip`\n\nWARNING: for linux, use [`musl`](https://en.wikipedia.org/wiki/Musl) instead of `gnu` (high chances of uncompatibility in the latter case)\n\nThe tar contains a single executable binary file.\n```bash\ntar xzvf vot-vxx-yyy.tar.gz\n./vot\n```\n\n\n### Compile from source code\n\n[Install rust](https://www.rust-lang.org/tools/install)\n(and check that `~/.cargo/bin/` is in your path),\nor update the Rust compiler with:\n```bash\nrustup update\n``` \n\nClone the [votable lib rust](https://github.com/cds-astro/cds-votable-rust) project:\n```bash\ngit clone https://github.com/cds-astro/cds-votable-rust\n```\nInstall from using `cargo`:\n```bash\ncargo install --all-features --path crates/cli\n```\n\n\n## Check 'vot' tool version\n\nOnce installed, check the version number using:\n```\n> vot --version\nvotable-cli 0.6.1\n```\n\n\n## Help messages\n\n```bash\n> vot --help\nCommand-line to extract/edit metadata from IVOA VOTables and to convert efficiently VOTable back and forth in XML-TABLEDATA, XML-BINARY, XML-BINARY2, non-standard JSON/YAML/TOML (and to CSV).\n\nUsage: vot <COMMAND>\n\nCommands:\n  convert   Convert a VOTable from one format to another (full table loaded in memory)\n  sconvert  Convert a single table XML VOTable in streaming mode\n  edit      Edit metadata adding/removing/updating attributes and/or elements\n  get       Get information from a VOTable: e.g. its structure or fields metadata\n  help      Print this message or the help of the given subcommand(s)\n\nOptions:\n  -h, --help     Print help\n  -V, --version  Print version\n```\n\n```bash\n> vot convert --help\nConvert a VOTable from one format to another (full table loaded in memory)\n\nUsage: vot convert [OPTIONS] --out-fmt <OUTPUT_FMT>\n\nOptions:\n  -i, --in <FILE>             Path of the input VOTable [default: read from stdin]\n  -t, --in-fmt <INPUT_FMT>    Format of the input VOTable (standard: 'xml'; not standard: 'json', 'yaml' or 'toml') [default: guess from file extension]\n  -o, --out <FILE>            Path of the output VOTable [default: write to stdout]\n  -f, --out-fmt <OUTPUT_FMT>  Format of the output VOTable (standard: 'xml', 'xml-td', 'xml-bin', 'xml-bin2'; not standard: 'json', 'yaml', 'toml')\n  -p, --pretty                Pretty print (for JSON and TOML)\n  -h, --help                  Print help\n```\n\n```bash\n> vot sconvert --help\nConvert a single table XML VOTable in streaming mode\n\nUsage: vot sconvert [OPTIONS] --out-fmt <OUTPUT_FMT>\n\nOptions:\n  -i, --in <FILE>                Path of the input XML VOTable [default: read from stdin]\n  -o, --out <FILE>               Path of the output file [default: write to stdout]\n  -f, --out-fmt <OUTPUT_FMT>     Format of the output file ('xml-td', 'xml-bin', 'xml-bin2' or 'csv')\n  -s, --separator <SEPARATOR>    Separator used for the 'csv' format [default: ,]\n      --parallel <N>             Exec concurrently using N threads\n      --chunk-size <CHUNK_SIZE>  Number of rows process by a same thread in `parallel` mode [default: 10000]\n  -h, --help                     Print help\n```\n\n```bash\n> vot get --help\nGet information from a VOTable: e.g. its structure or fields metadata\n\nUsage: vot get [OPTIONS] <COMMAND>\n\nCommands:\n  struct        Print the VOTable structure: useful to get Virtual IDs used in edition\n  colnames      Print column names, one line per table.\n  fields-array  Print selected field information as an array\n  help          Print this message or the help of the given subcommand(s)\n\nOptions:\n  -i, --in <FILE>           Path of the input VOTable [default: read from stdin]\n  -t, --in-fmt <INPUT_FMT>  Format of the input VOTable (standard: 'xml'; not standard: 'json', 'yaml' or 'toml') [default: guess from file extension]\n  -s, --early-stop          Stop parsing before reading first data ('xml' input only): useful for large single-table files\n  -h, --help                Print help\n```\n\n```bash\n> vot edit --help\nEdit metadata adding/removing/updating attributes and/or elements\n\nUsage: vot edit [OPTIONS] --out-fmt <OUTPUT_FMT>\n\nOptions:\n  -i, --in <FILE>             Path of the input VOTable [default: read from stdin]\n  -t, --in-fmt <INPUT_FMT>    Format of the input VOTable (standard: 'xml'; not standard: 'json', 'yaml' or 'toml') [default: guess from file extension]\n  -o, --out <FILE>            Path of the output VOTable [default: write to stdout]\n  -f, --out-fmt <OUTPUT_FMT>  Format of the output VOTable (standard: 'xml', 'xml-td', 'xml-bin', 'xml-bin2'; not standard: 'json', 'yaml', 'toml')\n  -p, --pretty                Pretty print (for JSON and TOML)\n  -e, --edit <ELEMS>          List of \"TAG CONDITION ACTION ARGS\", e.g.:\n                              -e 'INFO name=Target rm' -e 'FIELD ID=RA set_attrs ucd=pos.eq.ra;meta.main unit=deg'\n                              CONDITIONS:\n                                name=VAL  name (if any) equals a given value\n                                  id=VAL  id (if any) equals a given value\n                                 vid=VAL  virtual id equals a given value\n                              ACTIONS ARGS:\n                                rm                                                 Remove the TAG\n                                set_attrs        KEY=VAL (KEY=VAL) ...               Set TAG attributes\n                                set_content      CONTENT                             Set the content for `DESCRIPTION`, `INFO`, `LINK`, `PARAMRef` or `FIELDRef`\n                                set_desc         DESC                                Set the `DESCRIPTION` for `VOTABLE`, `RESOURCE`, `TABLE`, `FIELD`, `PARAM` or `GROUP`\n                                push_timesys     KEY=VAL (KEY=VAL) ...               Push a new `TIMESYS` in `VOTABLE` or `RESOURCE`\n                                set_min          KEY=VAL (KEY=VAL) ...               Set a new `MIN` for `VALUES`.\n                                set_max          KEY=VAL (KEY=VAL) ...               Set a new `MAX` for `VALUES`.\n                                push_option      KEY=VAL (KEY=VAL) ... (SUB_ACTIONS) Push the new `OPTION` in `VALUES` or `OPTION`\n                                set_values       KEY=VAL (KEY=VAL) ... (SUB_ACTIONS) Set the new `VALUES` for `FIELD` or `PARAM`\n                                push_info        KEY=VAL (KEY=VAL) ... (SUB_ACTION)  Push the new `INFO` in `VOTABLE`, `RESOURCE` or `TABLE`.\n                                push_post_info   KEY=VAL (KEY=VAL) ... (SUB_ACTION)  Push the new post-`INFO` in `VOTABLE`.\n                                push_link        KEY=VAL (KEY=VAL) ... (SUB_ACTION)  Push the new `LINK` in  `RESOURCE`, `TABLE`, `FIELD` or `PARAM`.\n                                push_fieldref    KEY=VAL (KEY=VAL) ... (SUB_ACTION)  Push the new `FIELDRef` in `COOSYS` or table-`GROUP`.\n                                push_paramref    KEY=VAL (KEY=VAL) ... (SUB_ACTION)  Push the new `PARAMRef` in `COOSYS` or `GROUP`.\n                                push_coosys      KEY=VAL (KEY=VAL) ... (SUB_ACTION)  Push the new `COOSYS` in `VOTABLE` or `RESOURCE`.\n                                push_group       KEY=VAL (KEY=VAL) ... (SUB_ACTIONS) Push the new `GROUP` in `VOTABLE` or `RESOURCE`.\n                                push_tablegroup  KEY=VAL (KEY=VAL) ... (SUB_ACTIONS) Push the new `GROUP` in `TABLE`.\n                                push_param       KEY=VAL (KEY=VAL) ... (SUB_ACTIONS) Push the new `PARAM` in `VOTABLE`, `RESOURCE`, `TABLE` or `GROUP`.\n                                push_field       KEY=VAL (KEY=VAL) ... (SUB_ACTIONS) Push the new `FIELD` in `TABLE`.\n                                prepend_resource KEY=VAL (KEY=VAL) ... (SUB_ACTIONS) Preprend the new `RESOURCE` in `VOTABLE` or `RESOURCE`.\n                                push_resource    KEY=VAL (KEY=VAL) ... (SUB_ACTIONS) Push the new `RESOURCE` in `VOTABLE` or `RESOURCE`.\n                              SUB ACTIONS:\n                                Sub-actions are the same as the ACTIONS (except `rm` which is not allowed).\n                                A sub-action stars with a `@`. Actually one can see `@` as an action separator with the\n                                main action at the left of the first `@` and all other actions being sub-actions applying on\n                                the element created by the main action (the parent element).\n                                E.g, in:\n                                  `push_param KEY=VAL ... @set_description ... @push_link ...`\n                                Both `set_description` an `push_link` are executed on the new `PARAM` built by `push_param`.\n                                For sub-actions to be executed on the last created element, you can double once the `@`:\n                                  `push_param KEY=VAL ... @set_description ... @push_link ... @@set_content CONTENT`\n                                Here `set_content` will be applied on the new `LINK` before pushing it in the new `PARAM`.\n                                After a `@@`, all sub-commands are executed on the last created element.\n                                To go up from one level in the element hierarchy, use `@<`:\n                                  `push_param KEY=VAL ... @set_description ... @push_link ... @@set_content CONTENT @< @push_link ...`\n                                You can use arbitrary deeply nested elements using `@@` and `@<`.\n                                Those three commands do not lead to the same hierarchy:\n                                  `push_group ... @push_group ... @push_group @@push_group @push_group (@<)`\n                                  `push_group ... @push_group ... @push_group @@push_group @@push_group (@<@<)`\n                                  `push_group ... @push_group ... @push_group @@push_group @< @push_group`\n                                Remark: `@@xxx` is a short version of `@> @xxx`.\n  -z, --vizier-org-names      Extract original column names from VizieR description ending by '(org_name)' and put it inn the non-standard 'viz:org_name' attribute, be aware of the risk of false-detections!\n  -s, --streaming             Use streaming mode: only for large XML files with a single table, and if the input format is the same as the output format\n  -h, --help                  Print help\n```\n\n## Examples\n\n### XML/JSON/TOML/YAML convertion \n\n```bash\n# In memory conversion of a VOTable from XML-TABLEDATA to JSON\nvot convert --in my_votable.xml --out my_votable.json --out-fmt json\n```\n\n### Streaming conversion XML-TD, XML-BIN, XML-BIN2 and CSV\n\n```bash\n# Streaming conversion of a VOTable from XML-TABLEDATA to XML-BINARY\nvot sconvert --in my_votable.xml --out my_votable.xml.b64  --out-fmt xml-bin\n# Streaming conversion from XML to CSV, in parallel, of a single large table\nvot sconvert --in my_votable.xml --out my_votable.csv --out-fmt csv --parallel 6\n```\n\n### Get metadata\n\n```bash\n# Get the structure of a VOTable with virtual identifier for each element\nvot get --in my_votable.xml struct --line-width 120\n# Get the structure of a large VOTable till first DATA tag is reached\nvot get --in my_votable.xml --early-stop struct --line-width 120\n# Get only the colum names of a large table, with a non-ascii separator\nvot get --in my_votable.xml --early-stop colnames --separator '\u25ae'\n# Get an array of fields metadata with selected informations\nvot get -in my_votable.xml fields-array index,name,datatype,arraysize,width,precision,unit,ucd,description --separator ,\n```\n\nSee chosen column metadata of [this votable](resource/test_edit.td.xml)\n```bash\n> vot get --in test_edit.td.xml fields-array name,datatype,arraysize,width,precision,unit,ucd,description\n    name    dt  a w p   unit    ucd                          desc                                                                                                                         \n   recno   int    8             meta.record                  Record number assigned by the VizieR team. Should Not be used for identification.                                            \n  f_GCTP  char  1               meta.code                    [*] Indicates a note in file \"errata.dat\"                                                                                    \n    GCTP float    7 2           meta.id;meta.main            Catalog number                                                                                                               \n    comp  char  1               meta.code.multip             Double star component                                                                                                        \n  RA1900  char 10      \"h:m:s\"  pos.eq.ra;meta.main          ?Right ascension hours (1900.0)                                                                                              \n  DE1900  char  9      \"d:m:s\"  pos.eq.dec;meta.main         ?Declination degrees (1900.0)                                                                                                \nu_RA1900  char  1               meta.code.error;pos.eq.ra    [:C] : = lower precision position                                                                                            \n    Vmag float    5 2    mag    phot.mag;em.opt.V            ?V magnitude or other magnitude                                                                                              \n  n_Vmag  char  1               meta.note                    P indicates blue passband                                                                                                    \n     B-V float    5 2    mag    phot.color;em.opt.B;em.opt.V ?B-V color                                                                                                                   \n     U-B float    5 2    mag    phot.color;em.opt.U;em.opt.B ?U-B color                                                                                                                   \n  r_Vmag  char  1               meta.ref;pos.frame           Source code for photometry                                                                                                   \n      MK  char  *               src.spType                   Spectral type                                                                                                                \n    r_MK  char  1               meta.ref;pos.frame           Source code for spectral type                                                                                                \n     var  char  9               meta.id                      Variable star name                                                                                                           \n      HR short    4             meta.id                      ?HR number [NULL integer written as an empty string]                                                                         \n    supp  char  1               meta.note                    [S] S=in Hoffleit BSS Cat. <V/36>                                                                                            \n      HD  char  7               meta.id                      HD number and component                                                                                                      \n      DM  char 10               meta.id                      DM identification and component                                                                                              \n    name  char  *               meta.id                      Star name                                                                                                                    \n      pm float    6 3 arcsec/yr pos.pm                       ?Total Proper motion                                                                                                         \n    pmPA short    3      deg    pos.posAng;pos.pm            ?Proper motion position angle [NULL integer written as an empty string]                                                      \n      pi float    7 4  arcsec   pos.parallax.trig            ?Weighted absolute parallax                                                                                                  \n    e_pi float    4 1    mas    stat.error                   ?Standard error of parallax                                                                                                  \n    q_pi  char  1               meta.code.qual               [ GFPX]Quality of interagreement                                                                                             \n    o_pi short    2             meta.number                  ?Number of parallax observations [NULL integer written as an empty string]                                                   \n  Simbad  char  *               meta.ref.url                 SIMBAD data for this star                                                                                                    \n_RA.icrs  char 10      \"h:m:s\"  pos.eq.ra                    Right ascension (ICRS) at Epoch=J2000, proper motions taken into account  (computed by VizieR, not part of the original data)\n_DE.icrs  char  9      \"d:m:s\"  pos.eq.dec                   Declination (ICRS) at Epoch=J2000, proper motions taken into account  (computed by VizieR, not part of the original data) \n```\n\nSee the `structure` (with Virtual IDs) of the previous table:\n```bash\n> vot get --in test_edit.td.xml struct\nVOTABLE vid=D\n  RESOURCE vid=DR1\n    RESOURCE vid=DR1R1\n      COOSYS vid=DR1R1C1 ID=t4-coosys-1 system=eq_FK4 equinox=B1900\n    TABLE vid=DR1T1 name=I/238A/picat nrows=8994\n      DESCRIPTION vid=DR1T1d content=The data file\n      PARAM vid=DR1T1P1 name=votable-version datatype=char value=1.99+ (14-Oct-2013) arraysize=19\n      PARAM vid=DR1T1P2 name=-ref datatype=char value=VOTx25520 arraysize=9\n      PARAM vid=DR1T1P3 name=-out.max datatype=char value=50000 arraysize=5\n      PARAM vid=DR1T1P4 name=queryParameters datatype=char value=4 arraysize=1\n        DESCRIPTION vid=DR1T1P4d content=-oc.form=dec\\n-source=I/238A\\n-out.all\\n-out.max=50000\n      FIELD vid=DR1T1F1 name=recno datatype=int width=8 ucd=meta.record\n        DESCRIPTION vid=DR1T1F1d content=Record number assigned by the VizieR team. Should Not be used for identific...\n        LINK vid=DR1T1F1l1 title=LINK\n          href=http://vizier.u-strasbg.fr/viz-bin/VizieR-5?-info=XML&-out.add=.&-source=I/238A/picat&recno=${recno}\n      ...\n```\n\n### Edit\n\nWhen editing a VOTable, you probably need Virtual IDs (vid) to select tags you want to remove or to modify.\nOne Virtual ID is attributed by votable-cli to each tag of the VOTable.\nTo know the vid attributed to each tag, you can use the `vot get ... struct` subcommand. \n\nIn the following example, we modify [this votable](resource/test_edit.td.xml) to:\n* remove the first sub-RESOURCE\n* add attributes to the main RESOURCE\n* add DESCRIPTION to the main RESOURCE\n* add COOSYS with FIELDref to the main resource\n* remove PARAMs\n* add a PARAM\n* rename the column `recno` into `RecordNumber` \n* remove a LINK\n* add an INFO to the TABLE\n* add a post-INFO to the VOTABLE\n\n\n```bash\n# Command used to get the vid (Virtual ID) of each tag in the VOTable\nvot get --in test_edit.td.xml struct \n\n# Command used to rename column 'recno' into 'RecordNumber'\n# (the 'streaming' option on such a small table is useless)\nvot edit --in test_edit.td.xml --out-fmt xml-td --streaming \\\n  -e 'FIELD name=recno set_attrs name=RecordNumber'\n\n# Command used to edit the VOTable\n# (the 'streaming' option on such a small table is useless)\nvot edit --in test_edit.td.xml --out-fmt xml-td --streaming \\\n  -e 'RESOURCE vid=DR1R1 rm' \\\n  -e 'RESOURCE vid=DR1 set_attrs ID=R1 name=main_resource' \\\n  -e 'RESOURCE vid=DR1 set_description The main resource containing my super table' \\\n  -e 'RESOURCE vid=DR1 push_coosys ID=t4-coosys-1 system=eq_FK4 equinox=B1900 \n        @push_fieldref ref=RA1900 \n\t  @@set_content Ref to the RA column @<\n        @push_fieldref ref=DE1900 \n\t  @@set_content Ref to the Declination column @<' \\\n  -e 'PARAM name=votable-version rm' \\\n  -e 'PARAM name=-ref rm' \\\n  -e 'PARAM name=-out.max rm' \\\n  -e 'PARAM name=queryParameters rm' \\\n  -e 'TABLE name=I/238A/picat push_param name=hpx_order datatype=unsignedByte value=8 \n       @set_description HEALPix order\n       @set_values \n         @@set_min value=0  inclusive=true \n\t  @set_max value=29 inclusive=true\n\t @<\n       @push_link href=https://en.wikipedia.org/wiki/HEALPix\n         @@set_content General HEALPix info on Wikipedia @<' \\\n  -e 'FIELD name=recno set_attrs name=RecordNumber' \\\n  -e 'LINK vid=DR1T1F27l1 rm' \\\n  -e 'TABLE name=I/238A/picat push_info name=ps value=my post-scriptum @set_content My super post-scriptum' \\\n  -e 'VOTABLE vid=D push_post_info name=warning value=This table has been modified by using vot-cli'\n```\n\n\n## Log messages\n\nYou can adapt the `level` of log messages using\nthe environement variable `RUST_LOG` with one of the following value:\n`error`, `warn`, `info`, `debug`, `trace` and `off`.\n\nE.g.:\n```bash\nRUST_LOG=\"trace\" vot get --in my_votable.xml struct\n```\n\nSee [env_logger](https://docs.rs/env_logger/latest/env_logger/) for more details.\n\n\n## Performances\n\nTo convert large tables, use the `sconvert` sub-command with the `--parallel` option.\n\nWARNING: so far, the `--parallel` option does not preserve the rows order, \nlet me know if it is problematic.\n\nTest on my computer:\n* Intel(R) Core(TM) i5-6600 (4 cores, 4 threads)\n* NVMe SSD\n\nInput file: `gaia_dr3.vot`\n* 2.8 GB\n* 225 columns\n* 999999 rows\n\n```bash\n# Convert from TABLEDATA to BINARY\ntime vot sconvert --in gaia_dr3.vot --out out.bin.vot --out-fmt xml-bin --parallel 3\n\nreal\t0m15,339s\nuser\t0m40,220s\nsys\t0m2,273s\n\n\n# Convert from TABLEDATA to BINARY2\ntime vot sconvert --in gaia_dr3.vot --out out.bin2.vot --out-fmt xml-bin2 --parallel 3\n\nreal\t0m17,157s\nuser\t0m43,255s\nsys\t0m2,297s\n\n\n# Convert from TABLEDATA to CSV\ntime vot sconvert --in gaia_dr3.vot --out out.csv --out-fmt csv --parallel 3\n\nreal\t0m11,392s\nuser\t0m33,875s\nsys\t0m1,413s\n\n\n# Convert from TABLEDATA to CSV\ntime vot sconvert --in out.bin.vot --out out.csv --out-fmt csv --parallel 3\n\nreal\t0m18,903s\nuser\t0m32,819s\nsys\t0m1,833s\n```\n\nWith `out.bin.vot` and `out.bin2.vot` about 1.5 and 1.6 GB respectively, \nand `out.csv` about 1.1 and 0.99 GB respectively.\n\n\nSame test on a fast server (lot of CPUs, NVMe RAID) with 20 threads:\n```\n# Convert from TABLEDATA to BINARY\ntime vot sconvert --in gaia_dr3.vot --out out.bin.vot --out-fmt xml-bin --parallel 20\n\nreal\t0m5,123s\nuser\t1m6,248s\nsys\t0m4,619s\n\n\n# Convert from TABLEDATA to BINARY2\ntime vot sconvert --in gaia_dr3.vot --out out.bin2.vot --out-fmt xml-bin2 --parallel 20\n\nreal\t0m5,465s\nuser\t1m9,436s\nsys\t0m4,106s\n\n\n# Convert from TABLEDATA to CSV\ntime vot sconvert --in gaia_dr3.vot --out out.csv --out-fmt csv --parallel 20\n\nreal\t0m4,539s\nuser\t0m53,226s\nsys\t0m3,574s\n\n\n# Convert from TABLEDATA to CSV\ntime vot sconvert --in out.bin.vot --out out.csv --out-fmt csv --parallel 20\n\nreal\t0m12,416s\nuser\t0m47,123s\nsys\t0m2,302s\n```\n\n## Similar tool\n\n(Please let me known if you want me to add another tool here!) \n\n### Astropy\n\nNot really a CLI tool, but you can write python scripts (and thus probably do anything you want)\nusing the [astropy.io.votable](https://docs.astropy.org/en/stable/io/votable/index.html) package.\nSo far, the main limitations seems to be related to [large files](https://github.com/astropy/astropy/issues/14577)\nand performances (?).\n\n\n### STILTS\n\nThe main other CLI tool I am aware of to convert between possibly large \nXML-TABLEDATA/XML-BINARY/XML-BINARY2 (and to CSV) is \n[stilts](https://www.star.bris.ac.uk/~mbt/stilts/) with the \n[votcopy](https://www.star.bristol.ac.uk/mbt/stilts/sun256/votcopy-usage.html) command.\n\nStilts also allows for metadata edition, see [tpipe](https://www.star.bris.ac.uk/~mbt/stilts/sun256/tpipe-usage.html)\ncommand with [colmeta](https://www.star.bris.ac.uk/~mbt/stilts/sun256/colmeta.html) or [setparam](https://www.star.bris.ac.uk/~mbt/stilts/sun256/setparam.html) \n[procesing filter](https://www.star.bris.ac.uk/~mbt/stilts/sun256/filterSteps.html), but:\n* if data/metadata editing is required, VOTable structure may change\n* editing of VOTable-specific metadata is not always possible\n\nStilts is a very general, rich, efficient and robust tool with a lot of options to be explored.\n\nRegarding performances, the single threaded version of `vot-cli` shows performances similar to `stilts vocopy`.\nThe multi-threaded version of `vot sconvert` (i.e. with `--parallel` option) may increase performances up to x10 \ndepending on the hardware, the VOTable file and the type of conversion.\n\n\n## To-Do list\n\n* [X] Support `CDATA` in `TD` tags\n* [X] Use the iterator to implement streaming transformations between DATATABLE/BINARY/BINARY2.\n* [X] Also implement streaming conversion to CSV.\n* [X] Add commands to modify a VOTable metadata.\n* [ ] Implement streaming mode for multiple tables (if it is really useful, please tell me).\n* [ ] Add commands to select/compute columns and filter rows?\n\n\n## License\n\nLike most projects in Rust, this project is licensed under either of\n\n* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or\n  http://www.apache.org/licenses/LICENSE-2.0)\n* MIT license ([LICENSE-MIT](LICENSE-MIT) or\n  http://opensource.org/licenses/MIT)\n\nat your option.\n\n\n## Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this project by you, as defined in the Apache-2.0 license,\nshall be dual licensed as above, without any additional terms or conditions.\n\n\n\n\n",
    "bugtrack_url": null,
    "license": "MIT OR Apache-2.0",
    "summary": "Command-line to extract/edit metadata from IVOA VOTables and to convert efficiently VOTable back and forth in XML-TABLEDATA, XML-BINARY, XML-BINARY2, non-standard JSON/YAML/TOML (and to CSV).",
    "version": "0.6.1",
    "project_urls": {
        "Homepage": "https://github.com/cds-astro/cds-votable-rust/tree/main/crates/cli",
        "repository": "https://github.com/cds-astro/cds-votable-rust/tree/main/crates/cli"
    },
    "split_keywords": [
        "ivoa",
        " votable",
        " xml"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "fdb6b37e73b0ddbd33fcf983bdf35236ae48917ce461f1b8f1b03e4da69b218c",
                "md5": "a7b917e5f240b4bb731599f5237e9615",
                "sha256": "03c88bd53d555fdd1411da204c1a1cc8c39c1d844bbdc240ed3eb52e437dc5f0"
            },
            "downloads": -1,
            "filename": "votable_cli-0.6.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl",
            "has_sig": false,
            "md5_digest": "a7b917e5f240b4bb731599f5237e9615",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 5869135,
            "upload_time": "2024-04-15T15:05:56",
            "upload_time_iso_8601": "2024-04-15T15:05:56.042069Z",
            "url": "https://files.pythonhosted.org/packages/fd/b6/b37e73b0ddbd33fcf983bdf35236ae48917ce461f1b8f1b03e4da69b218c/votable_cli-0.6.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "f2c110f2546ba2601d521fd2780a1654d0a4554714bf3b1a71d53e4251708122",
                "md5": "6af197de54a6c79a7d7c3baf4de03fa7",
                "sha256": "94408b98018336c080bd9fbd3d43bbbae9e281262bd19f1ae6e877c72d6aa4b3"
            },
            "downloads": -1,
            "filename": "votable_cli-0.6.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl",
            "has_sig": false,
            "md5_digest": "6af197de54a6c79a7d7c3baf4de03fa7",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 3189854,
            "upload_time": "2024-04-15T14:53:51",
            "upload_time_iso_8601": "2024-04-15T14:53:51.550526Z",
            "url": "https://files.pythonhosted.org/packages/f2/c1/10f2546ba2601d521fd2780a1654d0a4554714bf3b1a71d53e4251708122/votable_cli-0.6.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "2e866cbec9ba94fbc080ecd9ca60ebbbfb7acfc1d641a4af475daf1462431500",
                "md5": "e6eabc1302d4a80ae1dd4674268cbb03",
                "sha256": "0331412475d15c29ab728b2906232e05e31d12cffd288c5a74027091cd67a278"
            },
            "downloads": -1,
            "filename": "votable_cli-0.6.1-py3-none-manylinux_2_28_x86_64.whl",
            "has_sig": false,
            "md5_digest": "e6eabc1302d4a80ae1dd4674268cbb03",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 3198984,
            "upload_time": "2024-04-15T14:51:43",
            "upload_time_iso_8601": "2024-04-15T14:51:43.546714Z",
            "url": "https://files.pythonhosted.org/packages/2e/86/6cbec9ba94fbc080ecd9ca60ebbbfb7acfc1d641a4af475daf1462431500/votable_cli-0.6.1-py3-none-manylinux_2_28_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "f047a5c1109ef27dbe8ff2f51da3a7af45ccdbc3addf83d6c67b091a49b47602",
                "md5": "2fa39e2579c63f385b326b68ecab0471",
                "sha256": "1ae503de92d8b9e2596a8e8584aa5082400437f4ca9fb5e685ada140d5936fb7"
            },
            "downloads": -1,
            "filename": "votable_cli-0.6.1-py3-none-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "2fa39e2579c63f385b326b68ecab0471",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 3038609,
            "upload_time": "2024-04-15T14:54:32",
            "upload_time_iso_8601": "2024-04-15T14:54:32.604524Z",
            "url": "https://files.pythonhosted.org/packages/f0/47/a5c1109ef27dbe8ff2f51da3a7af45ccdbc3addf83d6c67b091a49b47602/votable_cli-0.6.1-py3-none-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "7c8585dcfeee6f08e373080556cbeadc3479a1d3758b273bc221130b519e3b87",
                "md5": "6ebaa8386db1a946275076f0b13111fb",
                "sha256": "916cc95e15c912dead3570e44dc8cc5994dc81d43ca48d9f253566e4b514d4ee"
            },
            "downloads": -1,
            "filename": "votable_cli-0.6.1.tar.gz",
            "has_sig": false,
            "md5_digest": "6ebaa8386db1a946275076f0b13111fb",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 177315,
            "upload_time": "2024-04-15T14:51:46",
            "upload_time_iso_8601": "2024-04-15T14:51:46.295668Z",
            "url": "https://files.pythonhosted.org/packages/7c/85/85dcfeee6f08e373080556cbeadc3479a1d3758b273bc221130b519e3b87/votable_cli-0.6.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-04-15 14:51:46",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "cds-astro",
    "github_project": "cds-votable-rust",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "votable-cli"
}
        
Elapsed time: 2.89971s