Skip to main content

File parser and writer for optical time-domain reflectometry interchange files (Bellcore SOR)

Project description

otdrs

otdrs is a Rust implementation of a SOR file parser and generator. SOR files are used as a storage format for optical time-domain reflectometry (OTDR) tests, which are commonly used to characterise and validate the proper construction of fibre optic networks. SOR is formally known as the Bellcore OTDR interchange format, specified in Telcordia SR-4731, a proprietary standard. OTDR testing involves firing short pulses of light down fibres under test, and measuring the intensity of returned light over time.

otdrs is intended as a minimal but valid and robust parser implementation to enable a translation from the closed binary format to open, self-documenting formats, to permit easy development of analysis tools without having to deal with the complexities of managing a binary format that is broadly undocumented and difficult to parse. It also provides Rust primitives for OTDR files and a writer to allow files to be loaded, modified, and written back.

Wherever possible, translation preserves the input format; otdrs does not try to fix peculiarities of particular test equipment or post-processing software or work around quirks in their input, except where they would break parsing of the format. No normalisation is attempted.

Where the parser cannot reliably extract information it is omitted; in this sense, otdrs is a best-effort parser.

Writing of files is performed with as much care as possible and the optional checksum block is computed. Generated files open without issue in several professional applications, and proprietary data is preserved losslessly.

Rust was chosen for its robustness, type-safety, and the excellent nom parser library. serde is used for serialisation for output.

Rust Cargo Downloads Python

Usage

otdrs takes one positional argument, the path to a SOR file. Its output is a single JSON or CBOR blob which contains the information within the SOR file; flags are used to set the output path (default is stdout) or the format to output. otdrs --help shows the available options.

A post-processing example is shown in the demo.py script in this repository, which will plot the data from an OTDR file.

Installing

If you have Rust/Cargo installed you can install otdrs with cargo install otdrs. otdrs is not otherwise packaged currently.

Library Usage

You can use otdrs as a Rust library to read, modify, and write SOR files. For instance, the following minimal program will modify the fiber ID and cable ID of the file, and print the nominal wavelength of the file to the terminal.

use otdrs::parser::parse_file;
use std::fs::File;
use std::io::prelude::*;
fn main() -> std::io::Result<()>  {
    // Read the file into memory
    let mut in_file = File::open("input.sor")?;
    let mut in_data = Vec::new();
    in_file.read_to_end(&mut in_data)?;
    // Parse the file
    let mut sor = parse_file(&in_data).unwrap().1;
    // Most blocks are Options because the parser can't guarantee them
    // This is true even of "required" blocks in the spec, because otdrs is permissive.
    match sor.general_parameters.as_mut() {
        Some(mut gp) => {
            // If we've got a block we can read and modify it!
            println!("Nominal wavelength of this SOR record: {:?}", gp.nominal_wavelength);
            gp.fiber_id = "Hello world";
            gp.cable_id = "Foo bar";
            // Note that we don't check the values you write a valid, outside of type enforcement
            // Even then you need to be careful to adhere to the spec. e.g. no UTF-8 glyphs
            // No emojis in your comments field 😭😭😭
        }
        None => {
            println!("Your SOR file has no General Parameters block!")
        }
    }
    // Encode the SORFile structure to a binary SOR file again...
    // Note you'd normally want to handle errors properly here, but we're an example, so...
    let bytes_to_write = sor.to_bytes().unwrap();
    // Write the file out to disk!
    let mut out_file = File::create("output.sor").unwrap();
    out_file.write_all(&bytes_to_write)?;
    return Ok(());
}

Python module

otdrs is also available as a Python module, with limited functionality. Currently, reading SOR files is supported.

import otdrs
sor_from_file = otdrs.parse_file("input.sor")
sor_from_file.fixed_parameters.acquisition_offset #=> returns the acquisition offset, and so on
file = open("input.sor", "rb")
sor_from_bytes = otdrs.parse_bytes(file.read())
sor_from_bytes == sor_from_file #=> True

The resulting objects and methods are fully type hinted.

Code Quality, Conformance/Compliance

This is the author's first major Rust project, so use with caution.

This is absolutely not guaranteed to work in all cases with all files or produce correct output in all cases (or indeed any). Check the output with the files you're using and a known-good viewer if you care about what you're doing.

Security Considerations

As otdrs handles arbitrary binary input and performs some arithmetic on it which can potentially lead to underruns and overruns as well as exciting undefined behaviour.

While Rust is a very good language to write such tools in, since runtime errors such as this are handled, otdrs makes an effort to avoid obvious situations where slice pointers violate bounds or where arithmetic on SOR contents may lead to unexpected situations. cargo-fuzz is used to fuzz with libFuzzer (on Linux only at present) to discover scenarios in which this can occur, including through writing and round-tripping OTDR files.

Checking of result validity is not performed on all fields, and users of the tool should take care to avoid trusting input parsed from SOR files. Sanitise your inputs.

Known Issues

  • The "link parameters" block is not currently decoded, as the author does not have files which contain it for testing. This is not used in common OTDR sets.
  • Testing is not as comprehensive and extensive as it should be, particularly for writing files.

There is no application of fixed scaling factors described in SR-4731. This is generally intentional, to permit correct post-processing as required in other applications.

Proprietary Blocks

While SOR files are standardised, not all of the content is; there are a set of standard and required blocks for the basic information, and otdrs only attempts to parse the standard blocks in a SOR file.

The content of proprietary blocks is dumped for analysis by upstream tools that may either have knowledge of proprietary formats or wish to simply know of the existence of such blocks. The map block will in all cases list all blocks within the file.

Writing SORs

otdrs has experimental support for generating SORs from Rust data structures. Strictly, the map block is heavily recomputed when writing; a BlockInfo block with a revision number and header will be expected for all blocks, but sizes and counters are dynamically generated. This is because it is practically impossible (or very difficult, at least) to compute sizes before serialising data, so this is best done at the point of writing.

Editors are responsible for ensuring that any modification of data elsewhere in the file makes sense, e.g. if the number of points within a DataPointsAtScaleFactor struct is changed, then the n_points field must be amended by the editor; otdrs will not do this for you.

Currently, landmarks and LinkParameters are not written out, as these are very rarely used in practice and no example data is currently available to support testing.

Testing

The parser has been tested on SOR files generated from:

  • Noyes OFL280 OTDRs, including those re-exported from EXFO FastReporter3
  • Anritsu Access Master OTDRs
  • EXFO MaxTester 730C and FTB-4/FTBx730 OTDRs
  • EXFO iOLM files exported to SOR from EXFO FastReporter3
  • EXFO 735C-SM7R modules in centralised PON test deployments (shooting through splitters to high-reflectance devices)

Round-trip testing has also confirmed that all of the above files can be read and written out by otdrs with no loss or alteration of data.

Further test files are desired and should be submitted to the author or as a pull request with tests against known values.

Interpretation

To actually interpet any of this data correctly you are probably going to need to read SR-4731, which can be found here for around $750.

This parser makes no attempt to correctly interpret the resulting data from the SOR file format, merely to make it accessible for applications to perform correct interpretation. Actually locating events and measuring cable data based on OTDR data requires careful consideration of data offsets (e.g. front panel to user offset, scaling factors, etc).

Vendor Quirks

As with pretty much every standard out there, every vendor has interpreted it differently. For one example, some Noyes OTDRs store a 30 second averaging period as 3000 whereas EXFO and Anritsu record it as 30. The specification, of course, says this should be stored as 300. Professional software struggles with this - for instance, EXFO's FastReporter3 software misinterprets the Noyes result.

Documentation of storage quirks compared to "standard" behaviour such as the above, against known behaviour would be helpful for those developing post-processing software; if you have access to test equipment, you can helpfully run a controlled test, write down the actual values displayed by the tester etc and store the SOR file directly.

While "fixing" vendor quirks to generate a standards-compliant output is not currently in the scope of otdrs, this is something that could be added as an optional post-processing step.

Versions

  • 1.0.2 - Python module added as an optional feature
  • 1.0.1 - upgraded nom to 8.0.0, clap to 4.x
  • 1.0.0 - refactored to avoid some beginner Rust errors; SORFile now owns its data. Updated dependencies.
  • 0.4.2 - upgraded nom to 7.1.0, clap to 3.0.0-rc7
  • 0.4.1 - upgraded nom to 6.1.2, improved README and demo scripts
  • 0.4.0 - added SORFile#to_bytes and a whole bunch of related functions and macros which altogether mean that otdrs can now write OTDR files
  • 0.3.0 - switched to using clap for command-line argument handling for better error handling, added option to write to file instead of stdout and added CBOR export support
  • 0.2.0 - restructured to allow use as a library, added fuzzing and fixed a number of bounds-check/error propogation problems
  • 0.1.0 - initial release

License

GPLv3 has been selected specifically to drive improved open source engagement with equipment manufacturers and developers of OTDR processing software in an industry that has struggled with open data exchange, proprietary (and vendor-locked) software, and poor maintenance of existing software.

otdrs - a SOR file parsing tool Copyright (C) 2021 James Harrison

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

otdrs-1.0.3.tar.gz (657.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

otdrs-1.0.3-cp313-cp313t-win_amd64.whl (202.5 kB view details)

Uploaded CPython 3.13tWindows x86-64

otdrs-1.0.3-cp313-cp313t-win32.whl (188.6 kB view details)

Uploaded CPython 3.13tWindows x86

otdrs-1.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl (520.6 kB view details)

Uploaded CPython 3.13tmusllinux: musl 1.2+ x86-64

otdrs-1.0.3-cp313-cp313t-musllinux_1_2_i686.whl (547.1 kB view details)

Uploaded CPython 3.13tmusllinux: musl 1.2+ i686

otdrs-1.0.3-cp313-cp313t-musllinux_1_2_armv7l.whl (614.8 kB view details)

Uploaded CPython 3.13tmusllinux: musl 1.2+ ARMv7l

otdrs-1.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl (525.4 kB view details)

Uploaded CPython 3.13tmusllinux: musl 1.2+ ARM64

otdrs-1.0.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (307.8 kB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.17+ x86-64

otdrs-1.0.3-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl (333.2 kB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.17+ i686

otdrs-1.0.3-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (286.1 kB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.17+ ARMv7l

otdrs-1.0.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (292.3 kB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.17+ ARM64

otdrs-1.0.3-cp313-cp313t-macosx_11_0_arm64.whl (311.5 kB view details)

Uploaded CPython 3.13tmacOS 11.0+ ARM64

otdrs-1.0.3-cp313-cp313t-macosx_10_12_x86_64.whl (321.1 kB view details)

Uploaded CPython 3.13tmacOS 10.12+ x86-64

otdrs-1.0.3-cp37-abi3-win_amd64.whl (205.8 kB view details)

Uploaded CPython 3.7+Windows x86-64

otdrs-1.0.3-cp37-abi3-win32.whl (193.3 kB view details)

Uploaded CPython 3.7+Windows x86

otdrs-1.0.3-cp37-abi3-musllinux_1_2_x86_64.whl (525.4 kB view details)

Uploaded CPython 3.7+musllinux: musl 1.2+ x86-64

otdrs-1.0.3-cp37-abi3-musllinux_1_2_i686.whl (551.7 kB view details)

Uploaded CPython 3.7+musllinux: musl 1.2+ i686

otdrs-1.0.3-cp37-abi3-musllinux_1_2_armv7l.whl (618.4 kB view details)

Uploaded CPython 3.7+musllinux: musl 1.2+ ARMv7l

otdrs-1.0.3-cp37-abi3-musllinux_1_2_aarch64.whl (529.8 kB view details)

Uploaded CPython 3.7+musllinux: musl 1.2+ ARM64

otdrs-1.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (312.8 kB view details)

Uploaded CPython 3.7+manylinux: glibc 2.17+ x86-64

otdrs-1.0.3-cp37-abi3-manylinux_2_17_i686.manylinux2014_i686.whl (337.9 kB view details)

Uploaded CPython 3.7+manylinux: glibc 2.17+ i686

otdrs-1.0.3-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (289.7 kB view details)

Uploaded CPython 3.7+manylinux: glibc 2.17+ ARMv7l

otdrs-1.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (296.4 kB view details)

Uploaded CPython 3.7+manylinux: glibc 2.17+ ARM64

otdrs-1.0.3-cp37-abi3-macosx_11_0_arm64.whl (323.0 kB view details)

Uploaded CPython 3.7+macOS 11.0+ ARM64

otdrs-1.0.3-cp37-abi3-macosx_10_12_x86_64.whl (334.0 kB view details)

Uploaded CPython 3.7+macOS 10.12+ x86-64

File details

Details for the file otdrs-1.0.3.tar.gz.

File metadata

  • Download URL: otdrs-1.0.3.tar.gz
  • Upload date:
  • Size: 657.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.9.2

File hashes

Hashes for otdrs-1.0.3.tar.gz
Algorithm Hash digest
SHA256 31ddf356d8440abe85d73a095d74f0df42f6bf1c06cbed0fe9305c7c459ee4cc
MD5 9cc535529952ab584534910f8a97fd10
BLAKE2b-256 9a437d01de0027f06322ca13617b9a56335e2deddfe109b2307a2723ac37b7f8

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp313-cp313t-win_amd64.whl.

File metadata

  • Download URL: otdrs-1.0.3-cp313-cp313t-win_amd64.whl
  • Upload date:
  • Size: 202.5 kB
  • Tags: CPython 3.13t, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.9.2

File hashes

Hashes for otdrs-1.0.3-cp313-cp313t-win_amd64.whl
Algorithm Hash digest
SHA256 adc4cc8cd4a0dce0ce822944408ddaa0fd1603504297cce449e1fa7052cc5300
MD5 a0ded117bf5e4be4d0a3b9f85cfea6b6
BLAKE2b-256 d536bb5a434a0477d420300266444e953dbc83c808b960134c8a004977bec0ec

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp313-cp313t-win32.whl.

File metadata

  • Download URL: otdrs-1.0.3-cp313-cp313t-win32.whl
  • Upload date:
  • Size: 188.6 kB
  • Tags: CPython 3.13t, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.9.2

File hashes

Hashes for otdrs-1.0.3-cp313-cp313t-win32.whl
Algorithm Hash digest
SHA256 9eb9d012e97972333d2a46b206a9284da47bc5b495102851e4f8cae6233a58df
MD5 3952fd5e08efe1304b2b76efd77642ae
BLAKE2b-256 78706423013d54b9c54e4086e89fd3c9ddb4984d00d69eeae93bd1a03fc7a8db

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 d5b1684c88895e3ad47e2e3655984ddd1b8e020bd1dec74289f5c8d81adb249c
MD5 dbc4e2fd280aca7ab5d8c54c18b309fb
BLAKE2b-256 264c773d340690b7d7202b96d3872fefee47bd7bc534b7fb7df41a276f893ef4

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp313-cp313t-musllinux_1_2_i686.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp313-cp313t-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 d2610017f3b256ae8f1f19df42a4b0ab6c0e5f08f32790b933d746a4ca4bfb59
MD5 7282729d200ced73517add3568eb244a
BLAKE2b-256 a1e07eebad73a6207ffa315dfc44b6859c59f6704839a6d9d93909d20befd5c5

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp313-cp313t-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp313-cp313t-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 b8db06c8cf29ca9c13ec85578dd2b332a2601c921cc37f17e8d01375f87b0603
MD5 d2a0ae10eb5f7a282f3bf906f72f084b
BLAKE2b-256 ab15e502236809cc4723b10585b126dc9aa87c9155f6ce2e6452f49f7b309648

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 c3028238294292c096430f83e7e4e340c147e933a7b9284e9113e7477e0fcb65
MD5 23ed7122f27f4a59f732693e7435eb02
BLAKE2b-256 d60011b7aab356d5b1f998b26c704528838b2f64d5df78a312c6040adc08a9a2

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e490054612dadc295f26c4a4720c580775e2ac2ad702a97856b1eaa8d969dc27
MD5 1175097785a659de58d75b9a3d9ad5e7
BLAKE2b-256 b73da8e0b92769dcc0757207ed726209980b325030440150e935c5b6ceecf2ad

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 78732b770303ea28330a0aa5b7b3d53b6366cc3a4d3a8c8d26b72f4d18c91ca9
MD5 18dac4de4f9899d68b82bf4f4d938691
BLAKE2b-256 0391e7749adb3c7a551935cd6a31143148bcf5d74f54437ea094789d27e725b0

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 3b4d7e8a825cf8887a66f801a2b0a249fb443041d8723e302b1c43937f0aab09
MD5 bec7c78d6d522e7c9e57bb199ba2ee2c
BLAKE2b-256 1faf41c5bf283c93a6cb4742cc7f71ed725fd2106beb92a0f59accf08e40ced3

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 188f1de13b00e90901cd5da7202778b851a1cf20670ba3a39e930efd0ea75e15
MD5 0ab55357e780df7ca2d4273581094e3e
BLAKE2b-256 38245a646b166b0c4013574642e9c83404f4bb9483f828bc83b60fc7771e99dd

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp313-cp313t-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp313-cp313t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f1abce2ac69a396856db189f346e9258fd2de27c3f4a7f2489d1d602c3103164
MD5 15d6e72c293c603ea9d510108fc45a09
BLAKE2b-256 decd8ea49431777e2cf6fe4fed46240366de3731558b00ff5465be1b818f0a88

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp313-cp313t-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp313-cp313t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 48e45dbf9cdabe0d18c4bdc2294dd92876727addea9bf361723d6b117be2454f
MD5 ab572762f213922e23fdbb8408fa2789
BLAKE2b-256 dffea36f66ff30cc6c6ff726bcc1f1f4d2e327b042533bd0ea70dee67186e83b

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp37-abi3-win_amd64.whl.

File metadata

  • Download URL: otdrs-1.0.3-cp37-abi3-win_amd64.whl
  • Upload date:
  • Size: 205.8 kB
  • Tags: CPython 3.7+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.9.2

File hashes

Hashes for otdrs-1.0.3-cp37-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 1d9de772110e8d2225f41d27f1d352039abcf3fbbc315b9f9928c0d29489df8b
MD5 5150870a3bb352c0edf7a465cacd9cae
BLAKE2b-256 2356851ed2f7e9cb119946e65c18d898ca25c680d33f56e5f1c857c68565f6b2

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp37-abi3-win32.whl.

File metadata

  • Download URL: otdrs-1.0.3-cp37-abi3-win32.whl
  • Upload date:
  • Size: 193.3 kB
  • Tags: CPython 3.7+, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.9.2

File hashes

Hashes for otdrs-1.0.3-cp37-abi3-win32.whl
Algorithm Hash digest
SHA256 ac548c09cf43571efb529f528002f2ecfc46a84ec53a33512070284d06faebde
MD5 efe324798999831a1e7ec9bda16547b2
BLAKE2b-256 8de6326b7d1ad36fda2c0c78ed35958587ef6cb22b9daaa6f524ddebbec35b8c

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp37-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp37-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 3b778226fd910c62dffb1cbe1f06ed90434ecf3e429608c21958338dde1ce935
MD5 64503409d34e2e01e7d164a4037daa04
BLAKE2b-256 cd6d19cfbabc0e0526ada3e05bf7eff53c4843ad3992b6c46c69452416b6f602

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp37-abi3-musllinux_1_2_i686.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp37-abi3-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 a34d52d1c84c5db6c85066123d6b19ffbfa2798493dfee54c26ac83b9df48cb7
MD5 cca8d898c3210633033c07e81c0f8869
BLAKE2b-256 36d0e7144d190ab5671c6692af8e738660dc21dd6e0acb312a5e23bef527b463

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp37-abi3-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp37-abi3-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 1373f9a0e10d79bbfae2d9742c314d92f75f53771048a981b531a96bfff130d6
MD5 01d91664014a972bc1c6727b756810dc
BLAKE2b-256 e734d0242245e51ef7dd29a14e8f5593ae69985b15edc03367636077963007dc

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp37-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp37-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 d26608e50db515c12e5f8fe2e76c0d4caf3e0920499715b1e1b58ca6b2ac54ae
MD5 5ac6b06046751c771f61baac02b6529a
BLAKE2b-256 a5a7720309d314b0f197a1425c2930f92c556e9ac1785c33c8b5156e79905ec1

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2959a8f192cf22042565bd945bb94f8c1489168c91431b8f044035788203f2f0
MD5 20737dda1145fe6e449945ce255c6c24
BLAKE2b-256 36b492d277e2af4e740381c1c17c72c2f9d88601e46dc940da6fdeba3aeb7a4b

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp37-abi3-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp37-abi3-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 c0fcd98c633e3a7f489a6b393a447e0d2da018c80fda55bc41bca8309bec7ccf
MD5 907fbbba663cbc9712293254e6cdfb8a
BLAKE2b-256 ad8d1c940dd8d3637acc29337b60e573b8dac491e7fad077a5721ec1a0c65b14

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 f51e7c429ffcc2941841a06b4fbc2746e2835058cbf47322215d69faba231051
MD5 9271c05de9afc48d51838f05ada07147
BLAKE2b-256 65ae6f06d2e8d4fa72be730c0fba5f19d96e4de3684df9f5d3141333228b958d

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 4f5984c1fa734bc9ef6eefbb2c9b0a758f1c05680d5e6dd89e499c1d0e07883c
MD5 1296bb577b14e93a578394f0ed44cd81
BLAKE2b-256 34e88d6038ca55ed47ac27bad4601c10222077357722b1bf9674bd667c455fd2

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp37-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp37-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8d481d2ded2a5d2b8e431658b1ecff8f934565237a3af9217d13fa0ca0e6738a
MD5 9018581700637337faa2d380bf1766af
BLAKE2b-256 c9f34b94caea48caffae14693201272db4f142143a768c01f6bed07fd699d86c

See more details on using hashes here.

File details

Details for the file otdrs-1.0.3-cp37-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for otdrs-1.0.3-cp37-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 0b1120dbfbf4b9e7483331200a0d7bf077a75ba7b3c34c0ada0a99bac509d00d
MD5 227f25ea13d81baf02c09b96f4b32ec4
BLAKE2b-256 34bc4caf0bae4ffa4d43848d9f524c0207e3a1d394a28c208cc836f96c9af9c2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page