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.4 - Python module type hints, dependency fix
  • 1.0.3 - Python module fixes
  • 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.4.tar.gz (657.3 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.4-cp313-cp313t-win_amd64.whl (202.5 kB view details)

Uploaded CPython 3.13tWindows x86-64

otdrs-1.0.4-cp313-cp313t-win32.whl (188.7 kB view details)

Uploaded CPython 3.13tWindows x86

otdrs-1.0.4-cp313-cp313t-musllinux_1_2_x86_64.whl (520.5 kB view details)

Uploaded CPython 3.13tmusllinux: musl 1.2+ x86-64

otdrs-1.0.4-cp313-cp313t-musllinux_1_2_i686.whl (547.0 kB view details)

Uploaded CPython 3.13tmusllinux: musl 1.2+ i686

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

Uploaded CPython 3.13tmusllinux: musl 1.2+ ARMv7l

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

Uploaded CPython 3.13tmusllinux: musl 1.2+ ARM64

otdrs-1.0.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (307.9 kB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.17+ x86-64

otdrs-1.0.4-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.4-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.4-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.4-cp313-cp313t-macosx_11_0_arm64.whl (311.5 kB view details)

Uploaded CPython 3.13tmacOS 11.0+ ARM64

otdrs-1.0.4-cp313-cp313t-macosx_10_12_x86_64.whl (321.0 kB view details)

Uploaded CPython 3.13tmacOS 10.12+ x86-64

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

Uploaded CPython 3.7+Windows x86-64

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

Uploaded CPython 3.7+Windows x86

otdrs-1.0.4-cp37-abi3-musllinux_1_2_x86_64.whl (525.3 kB view details)

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

otdrs-1.0.4-cp37-abi3-musllinux_1_2_i686.whl (551.8 kB view details)

Uploaded CPython 3.7+musllinux: musl 1.2+ i686

otdrs-1.0.4-cp37-abi3-musllinux_1_2_armv7l.whl (618.5 kB view details)

Uploaded CPython 3.7+musllinux: musl 1.2+ ARMv7l

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

Uploaded CPython 3.7+musllinux: musl 1.2+ ARM64

otdrs-1.0.4-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (312.9 kB view details)

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

otdrs-1.0.4-cp37-abi3-manylinux_2_17_i686.manylinux2014_i686.whl (337.8 kB view details)

Uploaded CPython 3.7+manylinux: glibc 2.17+ i686

otdrs-1.0.4-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (289.6 kB view details)

Uploaded CPython 3.7+manylinux: glibc 2.17+ ARMv7l

otdrs-1.0.4-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (296.5 kB view details)

Uploaded CPython 3.7+manylinux: glibc 2.17+ ARM64

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

Uploaded CPython 3.7+macOS 11.0+ ARM64

otdrs-1.0.4-cp37-abi3-macosx_10_12_x86_64.whl (334.2 kB view details)

Uploaded CPython 3.7+macOS 10.12+ x86-64

File details

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

File metadata

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

File hashes

Hashes for otdrs-1.0.4.tar.gz
Algorithm Hash digest
SHA256 e3e60a8d8613615fcacf3433d50e6238e10d4456179542264f463a95e4a53c94
MD5 eb337ed34907d4787802958dfd57901f
BLAKE2b-256 f83dc311c6dd42e3f7064c6bb6bd3cc38f486e006f0f231758d7653460914c5e

See more details on using hashes here.

File details

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

File metadata

  • Download URL: otdrs-1.0.4-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.4-cp313-cp313t-win_amd64.whl
Algorithm Hash digest
SHA256 199074174f0225da61e794caaf990dce24525de0d7798e308373a906ba6b42ed
MD5 7943862557fa8bb189d7a670326db913
BLAKE2b-256 b3fdb13385abd2cb1f175f4756fbed475e10b7146e5d27cf1bbd15c32734e7d5

See more details on using hashes here.

File details

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

File metadata

  • Download URL: otdrs-1.0.4-cp313-cp313t-win32.whl
  • Upload date:
  • Size: 188.7 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.4-cp313-cp313t-win32.whl
Algorithm Hash digest
SHA256 0177894d210d133380e6a86a93e8e8c586988eb52d9d9561b5d50c4b3cc7923a
MD5 7a0abb7636e1865e21696277f8581818
BLAKE2b-256 ce2aaf2b43e08777ba2f592a9d5aeac07f85467f274cec773e29c899f591050e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp313-cp313t-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 7d7b467803952230cacadaa5654304b84983802bc9da605c843d7f8a0f3cfd21
MD5 1a72db5040bb283470f8a427e18c021c
BLAKE2b-256 a4e194f0ef682d9d0715a9de6de16131c6098349612628448372950b65dfae3f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp313-cp313t-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 9095b85e2093d32831163fe07c6d9a7ac565dba8c613ba747ae33329f904e287
MD5 1ee94d0cf1f1f4a8fc8e05e6de188777
BLAKE2b-256 94e321c36c8cc00ed064f2cf697eebef98744d2f738f4cbfa5189e6d53eaaded

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp313-cp313t-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 99dd19bbc781f7ea7938bf74a540aa07b275dd01b4638c819ffc36583fe72f14
MD5 042da900a3529d78fab9142f6673c105
BLAKE2b-256 a198f69090f5c10fc8b80f8cc3e727ee4681f489d5001339a2b8b16a4b522caf

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp313-cp313t-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 3f2a06530528c0cf5b31d406cbf2ade180320f796f10736a40d619868456401f
MD5 f702403dedcca4182d877632f784e4c3
BLAKE2b-256 5b41f33a327b79f63443320512ea7ba4cebd78d0732ee7a1d45e1314f0f2e9e4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 240f5aaa124a6d89c41003fe870bd50317a087905b1254f892781e541a0db9dc
MD5 5b6fd1d6731cbaa9a321cf5221de05dc
BLAKE2b-256 0e79ec1d65d7129d8a968897cc2cb48ce6cfbd2e21562e9d81b9893283bc72a0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 f3f9d86538bf7ebc34f2fcd85e0573a6ce02c2373875ec4b02746ceaf85f6dbf
MD5 2a65936094d7861b333556e70ecdd5b2
BLAKE2b-256 13d9e173e9c108780fffa016fb2f4b795b9a003f2b64d03c6e3daaf22ec4d156

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 5764fe4bc7445497e281cd1c1fdc35849546e60a124401388d1ee50ad538aff8
MD5 93bc0a36260368d7060a17b6b9014590
BLAKE2b-256 25790edf375d1adea915532a5ed17a84a7db465fae6c62f3716b75175f00963f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 df7591b0438084248ddb3e8a7c3fe8c05428e114b52654c295dcbd3b41d5795e
MD5 302d750d28230365a443fbcdd920062d
BLAKE2b-256 1b032e3a0e9720c457fc5aa034162562ad17c196d26c0ba1ed1f11daba0bc261

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp313-cp313t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 bc26c5a5c3c0dde2a7f07e3583efbc326ffe41b401f5d40b347469a08cf957aa
MD5 f8f0eac5682e62cbf188c900911f74cd
BLAKE2b-256 cf414d19ed3cf21c93702927c1ebd5c53966ae20f52092047d995075b1105c98

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp313-cp313t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 a44a3dcaf98ff946ea6f843f093f1d9f195b1aee22d8465ef8e08359f3bf304f
MD5 c4da600d0a55cd07184d996fa6ab2d90
BLAKE2b-256 bb061d2ccf5247f1df0c46f025891f30717e18616d97dd87481b11c5a7c7d47c

See more details on using hashes here.

File details

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

File metadata

  • Download URL: otdrs-1.0.4-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.4-cp37-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 c8ece504f442cf58e081d3ed247c68a46b316da7d852690ffce915e18d1aa86e
MD5 eaebaa5af518508fe5f3efc346c803b5
BLAKE2b-256 fac5f340dd5b837a0b717f21c41251bbf65110731c406265467da6aae41f4ced

See more details on using hashes here.

File details

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

File metadata

  • Download URL: otdrs-1.0.4-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.4-cp37-abi3-win32.whl
Algorithm Hash digest
SHA256 036370a78c79f395a8ff9ff0163f33eab0787f59025281cd4a6d1cd1cc4dcec5
MD5 cec8fed15913a97c4118931c0f8c0ee0
BLAKE2b-256 2646a8b1baa4a81e72e5d1421fdb4eeab0e7f6ac3f4ba9eccaca762eb11264ea

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp37-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 85aa7eeaa354ee9cdabbcb7a44bf6b3afeb2cfdda17a5d0fdba5db12f0abfbc4
MD5 88e3aada470a5113b441519b1c21bd02
BLAKE2b-256 ea6c13beb8278493644304af7c71824ba803e5f35accae341b70a67aa783554a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp37-abi3-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 02d0181a3c43ba033d4bf5a462d17183ea03322e09fe80501ce72df515a691d5
MD5 c1a8115d4fbce36a86c6be443fcd37bb
BLAKE2b-256 0ada40b4122d990444707e22c758b7e51896dc9ca978874832496a7fa63f99e0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp37-abi3-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 c0c81bf2a10d125be73573b803ac4996003643ac8bda240ca24aa63adf88db2b
MD5 ae8b39cfabfaed0806a9f614db1cd814
BLAKE2b-256 91f7ae90addfc1bac06ffc286307c4b60447f00e11fbab9d14148e92bd609ab3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp37-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 d9a737af41bde4f62dfd5d94b006d36d2a13048b384017f278ca56660d4801ff
MD5 9bab832dbddcfb6cae19251890e66a00
BLAKE2b-256 b55921f50613a4119fd928ff9423d7b068152ed2629484a104243d1f924d1669

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 347ec061abc99c8eb92bdb463a8265469c97d1abf2cff32bf7f7e3a1f2635dac
MD5 4cf0a878c03295029298177c87d47b63
BLAKE2b-256 46829de865c1301df94f1cab2353f9470a7cde606000318c36e4216befd97dc9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp37-abi3-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 f9521d5f295764d9dcf45680a3897a3dc76d7d01e963ce082e85e5a1b55270b0
MD5 64003c1d5995020d017627a71499890a
BLAKE2b-256 d18bb273cd52d0311d2d6d54ac58310a1d720633dc167d0bddf9c8a173a4d3db

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 badae34c5d342fe9436548349a8509b327a03a65f1a02e93f2428aee7b1b76de
MD5 85abfdb6178713ffb96f9844bfcafd42
BLAKE2b-256 19c529761a275e849813dd577ce984510d97a108ef96f4d0a55ee1c0dea7b892

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 90e6deaf096be63a44b444c5c8d877fb9bde1c6b8ccf5b58ca863d9c07c09bb3
MD5 d54a556b2aaeb2830e95d88bb86bc228
BLAKE2b-256 a04f221d9037969468dacf65abcc7d5e35d1182665100b13a1ba2d4c088da40d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp37-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1fb62ed500385d4e5e4aa3f647a88f2b73f4b46c9e03d4414fd6f68bc28df901
MD5 fb9203ea2113ac45fc4b806542420b51
BLAKE2b-256 608f7f6a3ae2fa7c81eb637dd59e90a76dab8c5164edc859a99cf2d3437ae9fd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for otdrs-1.0.4-cp37-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 7473afddfc44d23907d2f5ec3f2de8570672f020635a2fc86605f2076a94dfa2
MD5 b5722436761a62d4a4d56a9db0460f68
BLAKE2b-256 0e50c26e951e9b76bbfc1af72e5c750b042a2b273966fda2cbc25583891c51f0

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