Scala
made by https://0x3d.site
GitHub - fingo/spata: Functional, stream-based CSV processor for ScalaFunctional, stream-based CSV processor for Scala. Contribute to fingo/spata development by creating an account on GitHub.
Visit Site
GitHub - fingo/spata: Functional, stream-based CSV processor for Scala
spata
spata is a functional tabular data (CSV
) processor for Scala.
The library is backed by FS2 - Functional Streams for Scala.
spata 3 supports Scala 3 only. Scala 2 support is still available in spata 2.
The main goal of the library is to provide handy, functional, stream-based API
with easy conversion between records and case classes, completed with precise information about possible flaws
and their location in source data for parsing while maintaining good performance.
Providing the location of the cause of a parsing error has been the main motivation to develop the library.
It is typically not that hard to parse a well-formatted CSV
file,
but it could be a nightmare to locate the source of a problem in case of any distortions in a large data file.
The source (while parsing) and destination (while rendering) data format is assumed to conform basically to
RFC 4180, but allows some variations - see CSVConfig
for details.
Getting started
spata 3 is available for Scala 3.x and requires at least Java 11.
To use spata you have to add this single dependency to your build.sbt
:
libraryDependencies += "info.fingo" %% "spata" % "<version>"
The latest version may be found on the badge above.
Link to the current API version is available through the badge as well.
Basic usage
The whole parsing process in a simple case may look like this:
import scala.io.Source
import cats.syntax.traverse.given // to get list.sequence
import cats.effect.IO
import cats.effect.unsafe.implicits.global // default IORuntime
import fs2.Stream
import info.fingo.spata.CSVParser
import info.fingo.spata.io.Reader
case class Data(item: String, value: Double)
val records = Stream
// get stream of CSV records while ensuring source cleanup
.bracket(IO(Source.fromFile("input.csv")))(source => IO(source.close()))
.through(Reader.plain[IO].by) // produce stream of chars from source
.through(CSVParser[IO].parse) // parse CSV file with default configuration and get CSV records
.filter(_.get[Double]("value").exists(_ > 1000)) // do some operations using Record and Stream API
.map(_.to[Data]) // convert records to case class
.handleErrorWith(ex => Stream.emit(Left(ex))) // convert global (I/O, CSV structure) errors to Either
val list = records.compile.toList.unsafeRunSync() // run everything while converting result to list
val result = list.sequence // convert List[Either[Throwable,Data]] to Either[Throwable,List[Data]]
Another example may be taken from FS2 readme,
assuming that the data is stored and written back in CSV
format with two fields, date
and temp
:
import java.nio.file.Paths
import scala.io.Codec
import cats.effect.{IO, IOApp}
import fs2.Stream
import info.fingo.spata.{CSVParser, CSVRenderer}
import info.fingo.spata.io.{Reader, Writer}
object Converter extends IOApp.Simple:
val converter: Stream[IO, Unit] =
given codec: Codec = Codec.UTF8
def fahrenheitToCelsius(f: Double): Double = (f - 32.0) * (5.0 / 9.0)
Reader[IO]
.read(Paths.get("testdata/fahrenheit.txt"))
.through(CSVParser[IO].parse)
.filter(r => r("temp").exists(!_.isBlank))
.map(_.altered("temp")(fahrenheitToCelsius))
.rethrow
.through(CSVRenderer[IO].render)
.through(Writer[IO].write(Paths.get("testdata/celsius.txt")))
def run: IO[Unit] = converter.compile.drain
Modified versions of this sample may be found in error handling and schema validation parts of the tutorial.
More examples of how to use the library may be found in src/test/scala/info/fingo/sample/spata
.
Tutorial
- Parsing
- Rendering
- Configuration
- Reading and writing data
- Getting actual data
- Creating and modifying records
- Text parsing and rendering
- Schema validation
- Error handling
- Logging
Parsing
Core spata operation is a transformation from a stream of characters into a stream of Record
s.
This is available through CSVParser.parse
method (supplying FS2 Pipe
)
and is probably the best way to include CSV
parsing into any FS2 stream processing pipeline:
val input: Stream[IO, Char] = ???
val parser: CSVParser[IO] = CSVParser[IO]
val output: Stream[IO, Record] = input.through(parser.parse)
In accordance with FS2, spata is polymorphic in the effect type and may be used with different effect implementations (Cats Effect IO or ZIO, especially with support for ZIO-CE interop; interoperability with Monix is not possible yet, but this may change in the future). Please note, however, that Cats Effect IO is the only effect implementation used for testing and documentation purposes.
Type class dependencies are defined in terms of the
Cats Effect class hierarchy.
To support effect suspension, spata requires in general cats.effect.Sync
type class implementation for its effect type.
Some methods need enhanced type classes to support asynchronous or concurrent computation.
Some are satisfied with more general effects.
Like in the case of any other FS2 processing, spata consumes only as much of the source stream as required, give or take a chunk size.
Field and record delimiters are required to be single characters. There are however no other assumptions about them - particularly the record delimiter does not have to be a line break and spata does not assume line break presence in the source data - it does not read the data by lines.
If newline (LF
, \n
, 0x0A
) is used as the record delimiter,
carriage return character (CR
, \r
, 0x0D
) is automatically skipped if not escaped, to support CRLF
line breaks.
Fields containing delimiters (field or record) or quotes have to be wrapped in quotation marks. As defined in RFC 4180, quotation marks in the content have to be escaped through double quotation marks.
By default, in accordance with the standard, whitespace characters are considered part of the field and are not ignored. Nonetheless, it is possible to turn on trimming of leading and trailing whitespaces with a configuration option. This differs from stripping whitespaces from resulting field content because it distinguishes between quoted and unquoted spaces. For example, having the following input:
X,Y,Z
xxx," yyy ",zzz
xxx, yyy ,zzz
without trimming the content of Y
field will be " yyy "
for both records.
With trimming on, we get " yyy "
for the first record and "yyy"
for the second.
Please also note, that the following content:
X,Y,Z
xxx, " yyy " ,zzz
is correct with trimming on (and produces " yyy "
for field Y
), but will cause an error without it,
as spaces are considered regular characters in this case and quote has to be put around the whole field.
Not all invisible characters (notably non-breaking space, '\u00A0'
) are whitespaces.
See Java's
Char.isWhitespace
for details.
If we have to work with a stream of String
s (e.g. from FS2 text.utf8.decode
or io.file.Files.readUtf8
),
we may used string-oriented parse method:
val input: Stream[IO, String] = ???
val output: Stream[IO, Record] = input.through(CSVParser[IO].parseS)
Alternatively, it is always possible to convert a stream of strings into a stream of characters:
val ss: Stream[IO, String] = ???
val sc: Stream[IO, Char] = ss.through(text.string2char)
In addition to the parse
, CSVParser
provides other methods to read CSV
data:
get
, to load data intoList[Record]
, which may be handy for small data sets,process
, to deal with data record by record through a callback function, synchronously,async
, to process data through a callback function in an asynchronous way.
The three above functions return the result (List
or Unit
) wrapped in an effect and require call to one of the
"at the end of the world" methods (unsafeRunSync
or unsafeRunAsync
for cats.effect.IO
) to trigger computation.
val stream: Stream[IO, Char] = ???
val parser: CSVParser[IO] = CSVParser[IO]
val list: List[Record] = parser.get(stream).unsafeRunSync()
Alternatively, instead of calling an unsafe function, the whole processing may run through IOApp.
See Reading and writing data for helper methods to get a stream of characters from various sources.
Rendering
Complementary to parsing, spata offers CSV
rendering feature -
it allows conversion from a stream of Record
s to a stream of characters.
This is available through CSVRenderer.render
method (supplying FS2 Pipe
):
val input: Stream[IO, Record] = ???
val renderer: CSVRenderer[IO] = CSVRenderer[IO]
val output: Stream[IO, Char] = input.through(renderer.render)
As with parsing, rendering is polymorphic in the effect type and may be used with different effect implementations.
The renderer has weaker demands for its effect type than parser and requires only the MonadError
type class implementation.
The render
method may encode only a subset of fields in a record. This is controlled by the header
parameter,
being optionally passed to the method:
val input: Stream[IO, Record] = ???
val header: Header = ???
val renderer: CSVRenderer[IO] = CSVRenderer[IO]
val output: Stream[IO, Char] = input.through(renderer.render(header))
The provided header is used to select fields and does not cause adding header row to output.
This is controlled by CSVConfig.hasHeader
parameter and may be induced even for render
method without header argument.
If no explicit header is passed to render
, it is extracted from the first record in the input stream.
If we have to create a stream of String
s (e.g. to pass to FS2 text.utf8.encode
or io.file.Files.writeUtf8
),
we may used string-oriented render method:
val input: Stream[IO, Record] = ???
val output: Stream[IO, String] = input.through(CSVRenderer[IO].renderS)
Alternatively, it is always possible to convert a stream of characters into a stream of strings:
val sc: Stream[IO, Char] = ???
val ss: Stream[IO, String] = sc.through(text.char2string)
Please note that using renderS
directly is more efficient than converting to characters,
because rendering uses stream of strings as an intermediary format anyway.
The main advantage of using CSVRenderer
over makeString
and intersperse
methods
is its ability to properly escape special characters (delimiters and quotation marks) in source data.
The escape policy is set through configuration and by default, the fields are quoted only when required.
Like parser, renderer supports any single-character field as record delimiters.
As result, the render
method does not allow separating records with CRLF
.
If this is required, the rows
method has to be used:
val input: Stream[IO, Record] = ???
val output: Stream[IO, String] = input.through(CSVRenderer[IO].rows).intersperse("\r\n")
The above stream of strings may be converted to a stream of characters as presented in the rendering part.
Unlike render
, the rows
method outputs all fields from each record and never outputs the header row.
See Reading and writing data for helper methods to transmit a stream of characters to various destinations.
Configuration
CSVParser
and CSVRenderer
are configured through CSVConfig
, which is a parameter to their constructors.
It may be provided through a builder-like method, which takes the defaults and allows altering selected parameters:
val parser = CSVParser.config.fieldDelimiter(';').noHeader.parser[IO]
val renderer = CSVRenderer.config.fieldDelimiter(';').noHeader.renderer[IO]
Individual configuration parameters are described in
CSVConfig
's Scaladoc.
A specific setting is the header mapping, available through CSVConfig.mapHeader
.
It allows replacing original header values with more convenient ones or even defining header if no one is present.
When set for the parser, the new values are then used in all operations referencing individual fields,
including automatic conversion to case classes or tuples.
The mapping may be defined only for a subset of fields, leaving the rest in their original form.
date,max temparature,min temparature
2020-02-02,13.7,-2.2
val stream: Stream[IO, Char] = ???
val parser: CSVParser[IO] =
CSVParser.config.mapHeader(Map("max temparature" -> "tempMax", "min temparature" -> "tempMin")).parser[IO]
val frosty: Stream[IO, Record] = stream.through(parser.parse).filter(_.get[Double]("minTemp").exists(_ < 0))
It may also be defined for more fields than there are present in any particular data source, which allows using a single parser for multiple datasets with different headers.
There is also index-based header mapping available. It may be used not only to define or redefine header but to remove duplicates as well:
date,temparature,temparature
2020-02-02,13.7,-2.2
val stream: Stream[IO, Char] = ???
val parser: CSVParser[IO] =
CSVParser.config.mapHeader(Map(1 -> "tempMax", 2 -> "tempMin")).parser[IO]
val frosty: Stream[IO, Record] = stream.through(parser.parse).filter(_.get[Double]("minTemp").exists(_ < 0))
Header mapping may be used for renderer too, to output different header values from those used by Record
or case class:
val stream: Stream[IO, Record] = ???
val renderer: CSVRenderer[IO] =
CSVRenderer.config.mapHeader(Map("tempMax" -> "max temparature", "tempMin" -> "min temparature")).renderer[IO]
val frosty: Stream[IO, Char] = stream.filter(_.get[Double]("minTemp").exists(_ < 0)).through(renderer.render)
FS2 takes care of limiting the amount of processed data and consumed memory to the required level.
This works well to restrict the number of records, nevertheless, each record has to be fully loaded into memory,
no matter how large it is.
This is not a problem if everything goes well - individual records are typically not that large.
A record can, however, grow uncontrollably in case of incorrect configuration (e.g. wrong record delimiter)
or malformed structure (e.g. unclosed quotation).
To prevent OutOfMemoryError
in such situations,
spata can be configured to limit the maximum size of a single field using fieldSizeLimit
.
If this limit is exceeded during parsing, the processing stops with an error.
By default, no limit is specified.
Reading and writing data
As mentioned earlier, CSVParser
requires a stream of characters as its input.
To simplify working with common data sources, like files or sockets, spata provides a few convenience methods,
available through its io.Reader
object.
Similarly, io.Writer
simplifies the process of writing a stream of characters produced by CSVRenderer
to an external destination.
There are two groups of the read
and write
methods in Reader
and Writer
:
-
basic ones, accessible through
Reader.plain
andWriter.plain
, where reading and writing is done synchronously on the current thread, -
with support for thread shifting, accessible through
Reader.shifting
andWriter.shifting
.
It is recommended to use the thread shifting version, especially for long reading or writing operations,
for better thread pool utilization.
See Cats Effect schedulers
description for thread pools configuration.
More information about threading may be found in
Cats Effect thread model.
The plain (non-shifting) versions could be useful when (for any reason),
the underlying effect system is limited to Sync
type class (the shifting versions require Async
),
or the data is read from scala.io.Source
- the shifting version may be less performant in some scenarios.
The simplest way to read data from and write to a file is:
val stream: Stream[IO, Char] = Reader[IO].read(Path.of("data.csv")) // Reader.apply is an alias for Reader.shifting
// do some processing on stream
val eff: Stream[IO, Unit] = stream.through(Writer[IO].write(Path.of("data.csv"))) // Writer.apply is an alias for Writer.shifting
There are explicit methods for reader and writer without thread shifting (doing i/o on current thread):
val stream: Stream[IO, Char] = Reader.plain[IO].read(Path.of("data.csv"))
// do some processing on stream
val eff: Stream[IO, Unit] = stream.through(Writer.plain[IO].write(Path.of("data.csv")))
The thread shifting reader and writer provide similar methods:
val stream: Stream[IO, Char] = Reader.shifting[IO].read(Path.of("data.csv"))
val eff: Stream[IO, Unit] = stream.through(Writer.shifting[IO].write(Path.of("data.csv")))
Cats Effect 3 provides the thread shifting facility out of the box through Async.blocking
,
using the built-in internal blocking thread pool.
All read
operations load data in chunks for better performance.
Chunk size may be supplied while creating a reader:
val stream: Stream[IO, Char] = Reader.plain[IO](1024).read(Path.of("data.csv"))
If not provided explicitly, a default chunk size will be used.
Except for Source
, which is already character-based,
other data sources and all data destinations require given instance of Codec
to convert bytes into characters:
given codec: Codec = Codec.UTF8
The caller to a read
or a write
method which takes a resource as a parameter (Source
, InputStream
or OutputStream
)
is responsible for its cleanup. This may be achieved through FS2 Stream.bracket
:
val stream: Stream[IO, Unit] = for
source <- Stream.bracket(IO(Source.fromFile("data.csv")))(source => IO(source.close()))
destination <- Stream.bracket(IO(new FileOutputStream("data.csv")))(fos => IO(fos.close()))
out <- Reader.shifting[IO].read(source)
// do some processing
.through(Writer[IO].write(destination))
yield out
Other methods of resource acquisition and releasing are described in Cats Effect tutorial.
Unlike the Reader.read
method, which creates a new stream, Writer.write
operates on an existing stream.
Being often the last operation in the stream pipeline, it has to allow access to the final stream,
being a handle to run the entire processing.
This is why write
returns a Pipe
, converting a stream of characters to a unit stream.
There is a by
method in Reader
, which returns a Pipe
too.
It converts a single-element stream containing data source into a stream of characters:
val stream: Stream[IO, Char] = Stream
.bracket(IO(Source.fromFile("data.csv")))(source => IO(source.close()))
.through(Reader.shifting[IO].by)
The parsing and rendering may be also backed up by FS2 I/O,
with possible support from FS2 text decoding and encoding.
Because those methods operate on a stream of strings instead of a stream of characters,
special, string-oriented methods for parsing (parseS
) and rendering ('renderS') should be used.
See parsing and rendering respectively.
Getting actual data
Sole CSV
parsing operation produces a stream of Record
s.
Each record may be seen as a map from String
to String
, where the keys, forming a header,
are shared among all records.
The basic method to obtain individual values is through the call to apply
, by key (taken from the header):
val record: Record = ???
val value: Option[String] = record("some key")
or index:
val record: Record = ???
val value: Option[String] = record(0)
CSV Record
supports retrieval of typed values.
In simple cases, when the value is serialized in its canonical form,
like ISO format for dates, which does not require any additional format information,
or the formatting is fixed for all data, this may be done with single-parameter get
function:
val record: Record = ???
val num: Decoded[Double] = record.get[Double]("123.45")
Decoded[A]
is an alias for Either[ContentError, A]
.
This method requires a text.StringParser[A]
, which is described in Text parsing.
get
has overloaded versions, which support formatting-aware parsing:
val record: Record = ???
val df = new DecimalFormat("#,###")
val num: Decoded[Double] = record.get[Double]("123,45", df)
This method requires a text.FormattedStringParser[A, B]
,
which is also described in Text parsing.
(It uses an intermediary class Field
to provide a nice syntax, but this should be transparent in most cases).
Above methods are available also in unsafe, exception-throwing version, accessible through Record.unsafe
object:
val record: Record = ???
val v1: String = record.unsafe("key")
val v2: String = record.unsafe(0)
val n1: Double = record.unsafe.get[Double]("123.45")
val df = new DecimalFormat("#,###")
val n2: Double = record.unsafe.get[Double]("123,45", df)
They may throw ContentError
exception.
In addition to retrieval of single fields, a Record
may be converted to a case class or a tuple.
Assuming a CSV
data in the following form:
element,symbol,melting,boiling
hydrogen,H,13.99,20.271
helium,He,0.95,4.222
lithium,Li,453.65,1603
the data can be converted from a record directly into a case class:
val record: Record = ???
case class Element(symbol: String, melting: Double, boiling: Double)
val element: Decoded[Element] = record.to[Element]
Notice that not all source fields have to be used for conversion. The conversion is name-based - header keys have to match case class field names exactly, including their case. We can use header mapping, described in Configuration, if they do not match.
For tuples, the header has to match traditional tuple field names (_1
, _2
, etc.)
and is automatically generated in this form for source data without a header:
hydrogen,H,13.99,20.271
helium,He,0.95,4.222
lithium,Li,453.65,1603
val record: Record = ???
type Element = (String, String, Double, Double)
val element: Decoded[Element] = record.to[Element]
Notice that in this case the first column has been included in the conversion to ensure header and tuple field matching.
Both forms of conversion require given instance of StringParser
.
Parsers for common types and their default formats are provided through StringParser
object
and are automatically brought in scope.
Because it is not possible to explicitly provide custom formatter while converting a record into a case class,
a given StringParser
instance has to be defined in case of specific formats or types:
element,symbol,melting,boiling
hydrogen,H,"13,99","20,271"
helium,He,"0,95","4,222"
lithium,Li,"453,65","1603"
val record: Record = ???
case class Element(symbol: String, melting: Double, boiling: Double)
val nf = NumberFormat.getInstance(new Locale("pl", "PL"))
given StringParser[Double] = (str: String) => nf.parse(str).doubleValue()
val element: Decoded[Element] = record.to[Element]
Creating and modifying records
A Record
is not only the result of parsing, it is also the source for CSV
rendering.
To let the renderer do its work, we need to convert the data to records first.
As mentioned above, a Record
is essentially a map from String
(key) to String
(value).
The keys form a header, which is, when only possible, shared among records.
This sharing is always in effect for records parsed by spata but requires some attention
when records are created by application code, especially when performance and memory usage matter.
Creating records
The basic way to create a record is to pass values as variable arguments:
val header = Header("symbol", "melting", "boiling")
val record = Record("H","13.99","20.271")(header)
val value = record("melting") // returns Some("13.99")
The header length is expected to match the number of values (arguments). If it does not, it is reduced (the last keys are omitted) or extended (tuple-style keys are added).
It is possible to create a record without providing a header and rely on the header that is implicitly generated:
val record = Record.fromValues("H","13.99","20.271")
val header = record.header // returns Header("_1", "_2", "_3")
val value = record("_2") // returns Some("13.99")
Because the record's header may be needless in some scenarios
(e.g. while using the index-based CSVRenderer.rows
method),
its implicit creation is lazy - it is postponed until the header is accessed.
If the header is created, each record gets its own copy.
A similar option provides record creation from key-value pairs:
val record = Record.fromPairs("symbol" -> "H", "melting" -> "13.99", "boiling" -> "20.271")
val value = record("melting") // returns Some("13.99")
This method creates a header per record and it should not be used with large data sets.
All three above methods require record values to be already converted to strings. However, what we often need, is to create a record from typed data, with proper formatting / locale. There are two methods to achieve that.
The first one is to employ a record builder, which allows adding typed values to the record one by one:
val record = Record.builder.add("symbol", "H").add("melting", 13.99).add("boiling", 20.271).get
val value = record("melting") // returns Some("13.99")
To convert a typed value to a string, this method requires a given StringRenderer[A]
instance,
which is described in Text rendering.
Similarly to StringParser
, renderers for basic types and formats are provided out of the box
and specific ones may be implemented:
val nf = NumberFormat.getInstance(new Locale("pl", "PL"))
given StringRenderer[Double] = (v: Double) => nf.format(v)
val record = Record.builder.add("symbol", "H").add("melting", 13.99).add("boiling", 20.271).get
val value = record("melting") // returns Some("13,99")
The second method allows direct conversion of cases classes or tuples to records:
case class Element(symbol: String, melting: Double, boiling: Double)
val element = Element("H", 13.99, 20.271)
val record = Record.from(element)
val value = record("melting") // returns Some("13.99")
This approach relies on StringRenderer
for data formatting as well.
It may be used even more comfortably by calling a method directly on case class:
import info.fingo.spata.Record.ProductOps
val nf = NumberFormat.getInstance(new Locale("pl", "PL"))
given StringRenderer[Double] = (v: Double) => nf.format(v)
case class Element(symbol: String, melting: Double, boiling: Double)
val element = Element("H", 13.99, 20.271)
val record = element.toRecord
val value = record("melting") // returns Some("13,99")
A disadvantage of both above methods operating on typed values is header creation for each record. They may be not the optimal choice for large data sets when performance matters.
Modifying records
Sometimes only a few fields of the original record have to be modified and the rest remains intact.
In such situations, it may be much more convenient to modify a record instead of creating a new one from scratch,
especially for large records.
Because Record
is immutable,
modifying means creation of a copy of the record with selected fields set to new values.
The simplest way is to provide a new string value for a record field, referenced by key or index:
val record: Record = ???
val modified: Record = record.updated(0, "new value").updated("key", "another value")
It is also possible to access existing value while updating record:
val record: Record = ???
val modified: Record = record.updatedWith(0)(v => v.toUpperCase).updatedWith("key")(v => v.toUpperCase)
Record provides a method to modify typed values too:
val record: Record = ???
val altered: Either[ContentError, Record] = record.altered("int value")((i: Int) => i % 2 == 0)
or in extended form:
val dateFormat = DateTimeFormatter.ofPattern("dd.MM.yy")
given StringParser[LocalDate] = (str: String) => LocalDate.parse(str, dateFormat)
given StringRenderer[LocalDate] = (ld: LocalDate) => dateFormat.format(ld)
val record: Record = ???
val altered: Either[ContentError, Record] = for
r1 <- record.altered("field 1")((d: Double) => d.abs)
r2 <- r1.altered("field 2")((ld: LocalDate) => ld.plusDays(1))
yield r2
Please note, however, that this method may produce an error
because the source values have to be parsed before being passed to the updating function.
To support value parsing and rendering,
given instances of StringParser[A]
and StringRenderer[B]
have to be provided for specific data formats.
All the above methods preserve record structure and keep existing record header. It is also possible to modify the structure, if necessary:
val record: Record = ???
val modified: Record = record.patch.remove("field 1").add("field 10", 3.14).get
Record.patch
employs RecordBuilder
to enhance or reduce record.
See Creating records above for more information.
Text parsing and rendering
CSV
data is parsed as String
s.
We often need typed values, e.g. numbers or dates, for further processing.
There is no standard, uniform interface available for Scala or Java to parse strings to different types.
Numbers may be parsed using java.text.NumberFormat
.
Dates and times through parse
methods in java.time.LocalDate
or LocalTime
, taking format as an argument.
This is awkward when providing a single interface for various types as Record
does.
This is the place where spata's text.StringParser
comes in handy.
The situation is similar when typed values have to be converted to strings to create CSV
data.
Although there is a toString
method available for each value, it is often insufficient,
because specific format of dates, numbers, and other values may be required.
Again, there is no single interface for encoding different types into strings.
spata provides text.StringRenderer
to help with this.
Similar solutions in other libraries are often called Decoder
and Encoder
in place of Parser
and Renderer
.
Parsing text
StringParser
object provides methods for parsing strings with default or implicitly provided format:
val num: ParseResult[Double] = StringParser.parse[Double]("123.45")
where ParseResult[A]
is just an alias for Either[ParseError, A]
.
When a specific format has to be provided, an overloaded version of the above method is available:
val df = new DecimalFormat("#,###")
val num: ParseResult[Double] = StringParser.parse[Double]("123,45", df)
(It uses intermediary class Pattern
to provide nice syntax,
this should be however transparent in most cases).
These functions require given StringParser
or FormattedStringParser
instance respectively.
Given instances for a few basic types are already available - see Scaladoc for StringParser
.
When additional parsers are required,
they may be easily provided by implementing StringParser
or FormattedStringParser
traits.
Let's take java.sql.Date
as an example. Having implemented StringParser[Date]
:
given sdf: StringParser[Date] = (s: String) => Date.valueOf(s)
we can use it as follows:
val date = StringParser.parse[Date]("2020-02-02")
Defining a parser with support for custom formatting requires the implementation of FormattedStringParser
:
given sdf: FormattedStringParser[Date, DateFormat] with
def apply(str: String): Date = Date.valueOf(str.strip)
def apply(str: String, fmt: DateFormat): Date = new Date(fmt.parse(str.strip).getTime)
and can be used as follows:
val df = DateFormat.getDateInstance(DateFormat.SHORT, new Locale("pl", "PL"))
val date = StringParser.parse[Date]("02.02.2020", df)
Please note that this sample implementation accepts partial string parsing,
e.g. "02.02.2020xyz"
will successfully parse to 2020-02-02
.
This is different from the built-in parsing behavior for LocalDate
,
where the entire string has to conform to the format.
Parsing implementations are expected to throw specific runtime exceptions when parsing fails.
This is converted to ParseError
in StringParser
object's parse
method
while keeping the original exception in the cause
field.
Although this design decision might be seen as questionable,
as returning Either
instead of throwing an exception could be a better choice,
it is made deliberately - all available Java parsing methods throw an exception,
so it is more convenient to use them directly while implementing StringParser
traits,
leaving all exception handling in a single place, i.e. the StringParser.parse
method.
Rendering text
Rendering is symmetrical with parsing.
StringRenderer
object provides methods for rendering strings with default or implicitly provided format:
val str: String = StringRenderer.render(123.45)
When a specific format has to be provided, an overloaded version of the above method is available:
val df = new DecimalFormat("#,###")
val str: String = StringRenderer.render(123.45, df)
These functions require given StringRenderer
or FormattedStringRenderer
instance respectively.
Given instances for a few basic types are already available - see Scaladoc for StringRenderer
.
When additional renderers are required,
they may be easily provided by implementing StringRenderer
or FormattedStringRenderer
traits.
Let's take again java.sql.Date
as an example. Having implemented StringRenderer[Date]
:
given sdf: StringRenderer[Date] = (d: Date) => if(d == null) "" else d.toString
we can use it as follows:
val date = Date.valueOf(LocalDate.now)
val str = StringRenderer.render(date)
Defining a renderer with support for custom formatting requires the implementation of FormattedStringRenderer
:
given sdf: FormattedStringRenderer[Date, DateFormat] with
def apply(date: Date): String = date.toString
def apply(date: Date, fmt: DateFormat): String = fmt.format(date)
and can be used as follows:
val df = DateFormat.getDateInstance(DateFormat.SHORT, new Locale("pl", "PL"))
val date = Date.valueOf(LocalDate.now)
val str = StringRenderer.render(date, df)
Schema validation
Successful CSV
parsing means that the underlying source has the correct format (taking into account parser configuration).
Nonetheless, the obtained records may have any content - being a collection of strings they are very permissive.
We often require strict data content and format to be able to use it in accordance with our business logic.
Therefore spata supports basic fields' format definition and validation.
CSV
schema can be defined using schema.CSVSchema
:
val schema = CSVSchema()
.add[String]("symbol")
.add[LocalDateTime]("time")
.add[BigDecimal]("price")
.add[String]("currency")
Schema is basically specified by the names of expected CSV
fields and their data types.
We do not need to include every field from the CSV
source in the schema definition.
It is enough to do it only for those fields we are interested in.
Schema is validated as part of a regular stream processing pipeline:
val schema = ???
val stream: Stream[IO, Char] = ???
val validatedStream = stream.through(CSVParser[IO].parse).through(schema.validate)
As a result of the validation process, the ordinary CSV
Record
is converted to ValidatedRecord[K,V]
,
which is an alias for Validated[InvalidRecord, TypedRecord[K,V]]
.
The parametric types K
and V
are the compile-time, tuple-based representations of the record keys and values.
Because they depend on the schema definition and are quite elaborate,
we are not able to manually provide it - we have to let the compiler infer it.
This is why the type signatures are omitted from some variable definitions in code excerpts in this chapter.
Validated is a Cats data type for wrapping validation results.
It is similar to Either
, with Valid
corresponding to Right
and Invalid
to Left
,
but more suitable for validation scenarios. Please reach for Cats documentation for an in-depth introduction.
The compile-time nature of this process makes future record handling fully type-safe:
val validatedStream = ???
validatedStream.map: validated =>
validated.map: typedRecord =>
val symbol: String = typedRecord("symbol")
val price: BigDecimal = typedRecord("price")
// ...
Please notice, that in contrast to the regular record, where the result is wrapped in Decoded[T]
,
we always get the straight type out of typed record.
If we try to access a non-existing field (not defined by schema) or assign it to a wrong value type,
we will get a compilation error:
val typedRecord = ???
val price: BigDecimal = typedRecord("prce") // does not compile
The key (field name) used to access the record value is a literal type. To be accepted by a typed record, the key has to be a literal value or a variable having a singleton type:
val typedRecord = ???
val narrow: "symbol" = "symbol" // singleton
val wide = "symbol" // String
val symbol1 = typedRecord("symbol") // OK
val symbol2 = typedRecord(narrow) // OK
val symbol3 = typedRecord(wide) // does not compile
Typed records, similarly to regular ones, support conversion to case classes:
case class StockPrice(symbol: String, price: BigDecimal)
val typedRecord = ???
val stockPrice: StockPrice = typedRecord.to[StockPrice]
Like in the case of regular records,
the conversion is name-based and may cover only a subset of a record's fields.
However, in contrast to a regular record, the result is not wrapped in Decoded
anymore.
A field declared in the schema has to be present in the source stream. Moreover, its values, by default, must not be empty. If values are optional, they have to be clearly marked as such in the schema definition:
val schema = CSVSchema()
.add[String]("symbol")
.add[Option[LocalDateTime]]("time")
Please note, that this still requires the field (column) to be present, only permits it to contain empty values.
While processing a validated stream, we have access to invalid data as well:
val validatedStream = ???
validatedStream.map: validated =>
validated.map: typedRecord =>
val price: BigDecimal = typedRecord("price")
// ...
.leftMap: invalid =>
val price: Option[String] = invalid.record("price")
// ...
(the above map
/leftMap
combination may be simplified to bimap
).
Schema validation requires string parsing, described in the previous chapter.
Similarly to the conversion to case classes, we are not able to directly pass a formatter to the validation,
so a regular StringParser
given instance with the correct format has to be provided for each parsed type.
All remarks described in Text parsing and rendering apply to the validation process.
Type verification, although probably the most important aspect of schema validation,
is often not the only constraint on CSV
required to successfully process the data.
We often have to check if the values match many other business rules.
spata provides a mean to declaratively verify basic constraints on the field level:
val schema = CSVSchema()
.add[String]("symbol", LengthValidator(3, 5))
.add[LocalDateTime]("time")
.add[BigDecimal]("price", MinValidator(BigDecimal(0.01)))
.add[String]("currency", LengthValidator(3))
Records that do not pass the provided schema validators render the result invalid, as in the case of a wrong type.
It is possible to provide multiple validators for each field.
The validation process for a field is stopped on the first failing validator.
The order of running validators is not specified.
Nevertheless, the validation is run independently for each field defined by the schema.
The returned InvalidRecord
contains error information from all incorrect fields.
The validators are defined in terms of typed (already correctly parsed) values.
A bunch of typical ones is available as part of info.fingo.spata.schema.validator
package.
Additional ones may be provided by implementing the schema.validator.Validator
trait.
The converter example presented in Basic usage may be improved to take advantage of schema validation:
import java.nio.file.Paths
import java.time.LocalDate
import scala.io.Codec
import cats.effect.{IO, IOApp}
import fs2.Stream
import info.fingo.spata.{CSVParser, CSVRenderer, Record}
import info.fingo.spata.io.{Reader, Writer}
import info.fingo.spata.schema.CSVSchema
object Converter extends IOApp.Simple:
val converter: Stream[IO, Unit] =
given codec: Codec = Codec.UTF8
val schema = CSVSchema().add[LocalDate]("date").add[Double]("temp")
def fahrenheitToCelsius(f: Double): Double = (f - 32.0) * (5.0 / 9.0)
Reader[IO]
.read(Paths.get("testdata/fahrenheit.txt"))
.through(CSVParser[IO].parse)
.through(schema.validate)
.map:
_.leftMap(_.toString).map: tr =>
val date = tr("date")
val temp = fahrenheitToCelsius(tr("temp"))
Record.builder.add("date", date).add("temp", temp).get
.evalMap:
_ match
case Invalid(s) => IO.println(s) >> IO.none
case Valid(r) => IO(Some(r))
.unNone
.through(CSVRenderer[IO].render)
.through(Writer[IO].write(Paths.get("testdata/celsius.txt")))
def run: IO[Unit] = converter.compile.drain
Error handling
There are three types of errors that may arise while parsing CSV
:
-
Various I/O errors, including but not limited to
IOException
. They are not directly related to parsing logic butCSV
is typically read from an external, unreliable source. They may be raised byReader
operations. -
Errors caused by malformed
CSV
structure reported asStructureException
. They may be caused byCSVParser
's methods. -
Errors caused by unexpected / incorrect data in record fields reported as one of
ContentError
subclasses. They may result from interactions withRecord
. Alternatively, when schema validation is in use, this type of error results inInvalidRecord
withSchemaError
s (one per each field) being yielded. More precisely,ContentError
is wrapped inTypeError
, while any custom validation problem is reported asValidationError
.
The two first error categories are unrecoverable and stop stream processing.
For the StructureException
errors, we can precisely identify the place that caused the problem.
See Scaladoc for CSVException
for further information about the error location.
The last category is reported on the record level and allows for different handling policies.
Please notice, however, that if the error is not handled locally (e.g. using safe functions returning Decoded
)
and propagates through the stream, further processing of input data is stopped, like for the above error categories.
As for rendering, there are basically two types of errors possible:
-
Errors caused by missing records keys, including records of different structures rendered together. They are reported on record level with
HeaderError
. -
Similarly to parsing, various I/O errors, when using
Writer
.
Errors are raised and should be handled by using the FS2 error handling mechanism.
FS2 captures exceptions thrown or reported explicitly with raiseError
and in both cases is able to handle them with handleErrorWith
.
To fully support this, CSVParser
and CSVRenderer
require the RaiseThrowable
type class instance for its effect type,
which is covered with cats.effect.Sync
type class for the parser.
The converter example presented in Basic usage may be enriched with explicit error handling:
import java.nio.file.Paths
import scala.io.Codec
import scala.util.Try
import cats.data.Validated.{Invalid, Valid}
import cats.effect.{ExitCode, IO, IOApp}
import fs2.Stream
import info.fingo.spata.{CSVParser, CSVRenderer, Record}
import info.fingo.spata.io.{Reader, Writer}
object Converter extends IOApp:
val converter: Stream[IO, ExitCode] =
def fahrenheitToCelsius(f: Double): Double = (f - 32.0) * (5.0 / 9.0)
given codec: Codec = Codec.UTF8
val src = Paths.get("testdata/fahrenheit.txt")
val dst = Paths.get("testdata/celsius.txt")
Reader[IO]
.read(src)
.through(CSVParser[IO].parse)
.filter(r => r("temp").exists(!_.isBlank))
.map: r =>
for
date <- r.get[String]("date")
fTemp <- r.get[Double]("temp")
cTemp = fahrenheitToCelsius(fTemp)
yield Record.builder.add("date", date).add("temp", cTemp).get
.rethrow
.through(CSVRenderer[IO].render)
.through(Writer[IO].write(dst))
.fold(ExitCode.Success)((z, _) => z)
.handleErrorWith: ex =>
Try(dst.toFile.delete())
Stream.eval(IO(println(ex)) *> IO(ExitCode.Error))
def run(args: List[String]): IO[ExitCode] = converter.compile.lastOrError
The rethrow
method in the above code raises an error for Left
, converting Either
to simple values.
Sometimes we would like to convert a stream to a collection.
We should wrap the result in Either
in such situations to distinguish successful processing from erroneous one.
See the first code snippet in Basic usage for sample.
Logging
Logging is turned off by default in spata (no-op logger)
and may be activated by defining given instance of util.Logger
,
passing an SLF4J logger instance to it:
val slf4jLogger = LoggerFactory.getLogger("spata")
given spataLogger: Logger[IO] = new Logger[IO](slf4jLogger)
spata does not create per-class loggers but uses the provided one for all logging operations.
All logging operations are deferred in the stream effect and executed as part of effect evaluation, together with main effectful operations.
The logging is currently limited to only a few events per parsed CSV
source (single info
entry,
a couple of debug
entries, and possibly an error
entry). There are no log events generated per CSV
record.
No stack trace is recorded for error
events.
The debug
level introduces additional operations on the stream and may slightly impact performance.
No parsed data is explicitly written to the log.
This can however occur when the CSV
source is assumed to have a header row, but it does not.
The first record of data is then assumed to be the header and is logged at debug level.
Please do not use the debug level if data security is crucial.
Alternatives
For those who need a different characteristic of a CSV
library, there are a few alternatives available for Scala:
- Itto-CSV -
CSV
handling library based on FS2 and Cats with support for case class conversion. Supports Scala 2 and 3. - fs2 data - collection of FS2 based parsers, including
CSV
. Part of typelevel-toolkit. Supports Scala 2 and 3. - kantan.csv - well documented
CSV
parser/serializer with support for different parsing engines. Available for Scala 2. - scala-csv - easy to use
CSV
reader/writer. Available for Scala 2 and 3. - cormorant - functional
CSV
processor with support for FS2, http4s and case class conversion. Available for Scala 2. - scala-csv-parser -
CSV
parser with support for conversion into case classes. Available for Scala 2. - TableParser - parser and renderer of tabular data in different formats, including
CSV
. - CVSSide - functional
CVS
parser with case class conversion. Available for Scala 2. - csv3s -
CSV
parser and renderer with case class conversion. Based on ZIO Parser. Supports Scala 3. - PureCSV (previously here) - easy to use
CSV
parser and renderer with case class conversion. Available for Scala 2. - ceesvee -
CSV
parser with case class conversion, designed for use with streams (FS2, ZStream). Support Scala 2 and 3. - Frugal Mechanic Flat File Reader - flat file (including
CSV
) reader/writer. Support Scala 2 and 3.
Credits
spata makes use of the following tools, languages, frameworks, libraries and data sets (in alphabetical order):
- Cats licensed under MIT /C
- Cats Effect licensed under Apache-2.0 /C
- Codecov available under following Terms of Use /D
- FS2 licensed under MIT /C
- Git licensed under GPL-2.0 /D
- GitHub available under following Terms of Service /D
- Gitter available under following Terms of Use /D
- IntelliJ IDEA CE licensed under Apache 2.0 /D
- javadoc.io licensed under Apache-2.0 /D
- Mars weather data made publicly available by NASA and CAB /T
- Metals licensed under Apache-2.0 /D
- OpenJDK licensed under GPL-2.0 with CE /C
- sbt licensed under BSD-2-Clause /D
- sbt-api-mappings licensed under Apache-2.0 /D
- sbt-dynver licensed under Apache-2.0 /D
- sbt-header licensed under Apache-2.0 /D
- sbt-license-report licensed under Apache-2.0 /D
- sbt-pgp licensed under BSD-3-Clause /D
- sbt-scoverage licensed under Apache-2.0 /D
- sbt-sonatype licensed under Apache-2.0 /D
- Scala licensed under Apache-2.0 /C
- Scalafix licensed under BSD-3-Clause /D
- Scalafmt licensed under Apache-2.0 /D
- ScalaMeter licensed under BSD-3-Clause /T
- ScalaTest licensed under Apache-2.0 /T
- shapeless licensed under Apache-2.0 /S
- SLF4J licensed under MIT /C
- sonatype OSSRH available under following Terms of Service /D
- Travis CI available under following Terms of Service /D
/C means compile/runtime dependency, /T means test dependency, /S means source code derivative and /D means development tool. Only direct dependencies are presented in the above list.
Run sbt dumpLicenseReport
to get a complete list of compile and runtime dependencies, including transitive ones.
spata build verifies whether all its dependencies are permissive so it can be deployed confidently in most usage scenarios.
More Resourcesto explore the angular.
mail [email protected] to add your project or resources here 🔥.
- 1A toolkit for servicing HTTP requests in Scala
https://github.com/unfiltered/unfiltered
A toolkit for servicing HTTP requests in Scala. Contribute to unfiltered/unfiltered development by creating an account on GitHub.
- 2A Scala DSL for talking with databases with minimum verbosity and maximum type safety
https://github.com/squeryl/squeryl
A Scala DSL for talking with databases with minimum verbosity and maximum type safety - squeryl/squeryl
- 3Apache Flink
https://github.com/apache/flink
Apache Flink. Contribute to apache/flink development by creating an account on GitHub.
- 4Vert.x for Scala
https://github.com/vert-x3/vertx-lang-scala
Vert.x for Scala. Contribute to vert-x3/vertx-lang-scala development by creating an account on GitHub.
- 5Chromaprint/AcoustID audio fingerprinting for the JVM
https://github.com/mgdigital/Chromaprint.scala
Chromaprint/AcoustID audio fingerprinting for the JVM - mgdigital/Chromaprint.scala
- 6A macro library that converts native imperative syntax to scalaz's monadic expressions
https://github.com/ThoughtWorksInc/each
A macro library that converts native imperative syntax to scalaz's monadic expressions - ThoughtWorksInc/each
- 7Incredibly simple DI Scala library.
https://github.com/yakivy/jam
Incredibly simple DI Scala library. Contribute to yakivy/jam development by creating an account on GitHub.
- 8Security library for Play framework 2 in Java and Scala: OAuth, CAS, SAML, OpenID Connect, LDAP, JWT...
https://github.com/pac4j/play-pac4j
Security library for Play framework 2 in Java and Scala: OAuth, CAS, SAML, OpenID Connect, LDAP, JWT... - pac4j/play-pac4j
- 9laserdisc-io/mysql-binlog-stream
https://github.com/laserdisc-io/mysql-binlog-stream
Contribute to laserdisc-io/mysql-binlog-stream development by creating an account on GitHub.
- 10GNU Gettext .po file loader for Scala
https://github.com/xitrum-framework/scaposer
GNU Gettext .po file loader for Scala. Contribute to xitrum-framework/scaposer development by creating an account on GitHub.
- 11Light-weight convenience wrapper around Lucene to simplify complex tasks and add Scala sugar.
https://github.com/outr/lucene4s
Light-weight convenience wrapper around Lucene to simplify complex tasks and add Scala sugar. - outr/lucene4s
- 12Workflow engine for exploration of simulation models using high throughput computing
https://github.com/openmole/openmole
Workflow engine for exploration of simulation models using high throughput computing - openmole/openmole
- 13PostgreSQL protocol support for Finagle
https://github.com/finagle/finagle-postgres
PostgreSQL protocol support for Finagle. Contribute to finagle/finagle-postgres development by creating an account on GitHub.
- 14Simple play module for authenticating against Google
https://github.com/guardian/play-googleauth
Simple play module for authenticating against Google - guardian/play-googleauth
- 15Extensible JOSE library for Scala
https://github.com/blackdoor/jose
Extensible JOSE library for Scala. Contribute to blackdoor/jose development by creating an account on GitHub.
- 16Large off-heap arrays and mmap files for Scala and Java
https://github.com/xerial/larray
Large off-heap arrays and mmap files for Scala and Java - xerial/larray
- 17A scala library for connecting to a redis server, or a cluster of redis nodes using consistent hashing on the client side.
https://github.com/debasishg/scala-redis
A scala library for connecting to a redis server, or a cluster of redis nodes using consistent hashing on the client side. - debasishg/scala-redis
- 18Idiomatic, typesafe, and reactive Scala client for Apache Pulsar
https://github.com/CleverCloud/pulsar4s
Idiomatic, typesafe, and reactive Scala client for Apache Pulsar - CleverCloud/pulsar4s
- 19Purely functional JSON parser and library in scala.
https://github.com/argonaut-io/argonaut
Purely functional JSON parser and library in scala. - argonaut-io/argonaut
- 20Modern Load Testing as Code
https://github.com/gatling/gatling
Modern Load Testing as Code. Contribute to gatling/gatling development by creating an account on GitHub.
- 21A Scala ORM library
https://github.com/kostaskougios/mapperdao
A Scala ORM library. Contribute to kostaskougios/mapperdao development by creating an account on GitHub.
- 22Docker containers for testing in scala
https://github.com/testcontainers/testcontainers-scala
Docker containers for testing in scala. Contribute to testcontainers/testcontainers-scala development by creating an account on GitHub.
- 23A scala diff/patch library for Json
https://github.com/gnieh/diffson
A scala diff/patch library for Json. Contribute to gnieh/diffson development by creating an account on GitHub.
- 24Testing tool in Scala for HTTP JSON API
https://github.com/agourlay/cornichon
Testing tool in Scala for HTTP JSON API. Contribute to agourlay/cornichon development by creating an account on GitHub.
- 25If you don't agree with the data
https://github.com/splink/veto
If you don't agree with the data. Contribute to splink/veto development by creating an account on GitHub.
- 26Software Specifications for Scala
https://github.com/etorreborre/specs2
Software Specifications for Scala. Contribute to etorreborre/specs2 development by creating an account on GitHub.
- 27The Couchbase Monorepo for JVM Clients: Java, Scala, io-core…
https://github.com/couchbase/couchbase-jvm-clients
The Couchbase Monorepo for JVM Clients: Java, Scala, io-core… - couchbase/couchbase-jvm-clients
- 28Salat is a simple serialization library for case classes.
https://github.com/salat/salat
Salat is a simple serialization library for case classes. - salat/salat
- 29Practical effect composition library based on abstract wrapping type and the free monad
https://github.com/ISCPIF/freedsl
Practical effect composition library based on abstract wrapping type and the free monad - ISCPIF/freedsl
- 30SevenZip library for Scala, easy to use.
https://github.com/gonearewe/SevenZ4S
SevenZip library for Scala, easy to use. . Contribute to gonearewe/SevenZ4S development by creating an account on GitHub.
- 31The super light testing library for Scala and Scala.js
https://github.com/monix/minitest
The super light testing library for Scala and Scala.js - monix/minitest
- 32A module that provides OAuth, OAuth2 and OpenID authentication for Play Framework applications
https://github.com/jaliss/securesocial
A module that provides OAuth, OAuth2 and OpenID authentication for Play Framework applications - jaliss/securesocial
- 33Compile-time Language Integrated Queries for Scala
https://github.com/zio/zio-quill
Compile-time Language Integrated Queries for Scala - zio/zio-quill
- 34Scala Scripting
https://github.com/com-lihaoyi/Ammonite
Scala Scripting. Contribute to com-lihaoyi/Ammonite development by creating an account on GitHub.
- 35Slick (Scala Language Integrated Connection Kit) is a modern database query and access library for Scala
https://github.com/slick/slick
Slick (Scala Language Integrated Connection Kit) is a modern database query and access library for Scala - slick/slick
- 36Property-based testing for Scala
https://github.com/typelevel/scalacheck
Property-based testing for Scala. Contribute to typelevel/scalacheck development by creating an account on GitHub.
- 37Simpler DynamoDB access for Scala
https://github.com/scanamo/scanamo
Simpler DynamoDB access for Scala. Contribute to scanamo/scanamo development by creating an account on GitHub.
- 38Type-Safe framework for defining, modifying, and querying SQL databases
https://github.com/outr/scalarelational
Type-Safe framework for defining, modifying, and querying SQL databases - outr/scalarelational
- 39ScalaFX simplifies creation of JavaFX-based user interfaces in Scala
https://github.com/scalafx/scalafx
ScalaFX simplifies creation of JavaFX-based user interfaces in Scala - scalafx/scalafx
- 40Performant database access in Scala
https://github.com/lucidsoftware/relate
Performant database access in Scala. Contribute to lucidsoftware/relate development by creating an account on GitHub.
- 41Scala library for boilerplate-free validation
https://github.com/krzemin/octopus
Scala library for boilerplate-free validation. Contribute to krzemin/octopus development by creating an account on GitHub.
- 42Connect a Scala REPL to running JVM processes without any prior setup
https://github.com/xitrum-framework/scalive
Connect a Scala REPL to running JVM processes without any prior setup - xitrum-framework/scalive
- 43A ZIO-based redis client
https://github.com/zio/zio-redis
A ZIO-based redis client. Contribute to zio/zio-redis development by creating an account on GitHub.
- 44Tiny Scala high-performance, async web framework, inspired by Sinatra
https://github.com/scalatra/scalatra
Tiny Scala high-performance, async web framework, inspired by Sinatra - scalatra/scalatra
- 45Reactive data-binding for Scala
https://github.com/ThoughtWorksInc/Binding.scala
Reactive data-binding for Scala. Contribute to ThoughtWorksInc/Binding.scala development by creating an account on GitHub.
- 46The Anorm database library
https://github.com/playframework/anorm
The Anorm database library. Contribute to playframework/anorm development by creating an account on GitHub.
- 47A module for the Play Framework to build highly modular applications
https://github.com/splink/pagelets
A module for the Play Framework to build highly modular applications - splink/pagelets
- 48I/O and Microservice library for Scala
https://github.com/tumblr/colossus
I/O and Microservice library for Scala. Contribute to tumblr/colossus development by creating an account on GitHub.
- 49Scala library to sign HTTP requests to AWS services.
https://github.com/ticofab/aws-request-signer
Scala library to sign HTTP requests to AWS services. - ticofab/aws-request-signer
- 50Next generation user interface and application development in Scala and Scala.js for web, mobile, and desktop.
https://github.com/outr/youi
Next generation user interface and application development in Scala and Scala.js for web, mobile, and desktop. - outr/youi
- 51Statistical Machine Intelligence & Learning Engine
https://github.com/haifengl/smile
Statistical Machine Intelligence & Learning Engine - haifengl/smile
- 52Microbenchmarking and performance regression testing framework for the JVM platform.
https://github.com/scalameter/scalameter
Microbenchmarking and performance regression testing framework for the JVM platform. - scalameter/scalameter
- 53A testing tool for Scala and Java developers
https://github.com/scalatest/scalatest
A testing tool for Scala and Java developers. Contribute to scalatest/scalatest development by creating an account on GitHub.
- 54:monorail: "Scala on Rails" - A full-stack web app framework for rapid development in Scala
https://github.com/skinny-framework/skinny-framework
:monorail: "Scala on Rails" - A full-stack web app framework for rapid development in Scala - skinny-framework/skinny-framework
- 55Molecule translates custom Scala code to database queries for multiple databases.
https://github.com/scalamolecule/molecule
Molecule translates custom Scala code to database queries for multiple databases. - scalamolecule/molecule
- 56Cryptographic primitives for Scala
https://github.com/input-output-hk/scrypto
Cryptographic primitives for Scala. Contribute to input-output-hk/scrypto development by creating an account on GitHub.
- 57A lightweight framework for writing REST services in Scala.
https://github.com/mesosphere/chaos
A lightweight framework for writing REST services in Scala. - mesosphere/chaos
- 58Async and clustered Scala web framework and HTTP(S) server
https://github.com/xitrum-framework/xitrum
Async and clustered Scala web framework and HTTP(S) server - xitrum-framework/xitrum
- 59A distributed tracing extension for Akka. Provides integration with Play framework, Spray and Akka HTTP.
https://github.com/levkhomich/akka-tracing
A distributed tracing extension for Akka. Provides integration with Play framework, Spray and Akka HTTP. - levkhomich/akka-tracing
- 60A simple FRP library and a web UI framework built on it
https://github.com/nafg/reactive
A simple FRP library and a web UI framework built on it - nafg/reactive
- 61Facebook's React on Scala.JS
https://github.com/japgolly/scalajs-react
Facebook's React on Scala.JS. Contribute to japgolly/scalajs-react development by creating an account on GitHub.
- 62Figaro Programming Language and Core Libraries
https://github.com/charles-river-analytics/figaro
Figaro Programming Language and Core Libraries. Contribute to charles-river-analytics/figaro development by creating an account on GitHub.
- 63Optimus is a mathematical programming library for Scala.
https://github.com/vagmcs/Optimus
Optimus is a mathematical programming library for Scala. - vagmcs/Optimus
- 64Fast JSON parser/generator for Scala
https://github.com/gzoller/ScalaJack
Fast JSON parser/generator for Scala. Contribute to gzoller/ScalaJack development by creating an account on GitHub.
- 65Apache Spark - A unified analytics engine for large-scale data processing
https://github.com/apache/spark
Apache Spark - A unified analytics engine for large-scale data processing - apache/spark
- 66scala SQL api
https://github.com/wangzaixiang/scala-sql
scala SQL api. Contribute to wangzaixiang/scala-sql development by creating an account on GitHub.
- 67Scala support library for integrating the JSON API spec with Spray, Play! or Circe
https://github.com/scala-jsonapi/scala-jsonapi
Scala support library for integrating the JSON API spec with Spray, Play! or Circe - scala-jsonapi/scala-jsonapi
- 68Scala code generator for Avro schemas.
https://github.com/malcolmgreaves/avro-codegen
Scala code generator for Avro schemas. Contribute to malcolmgreaves/avro-codegen development by creating an account on GitHub.
- 69Protocol buffer compiler for Scala.
https://github.com/scalapb/ScalaPB
Protocol buffer compiler for Scala. Contribute to scalapb/ScalaPB development by creating an account on GitHub.
- 70Functional JDBC layer for Scala.
https://github.com/tpolecat/doobie
Functional JDBC layer for Scala. Contribute to tpolecat/doobie development by creating an account on GitHub.
- 71CPU and GPU-accelerated Machine Learning Library
https://github.com/BIDData/BIDMach
CPU and GPU-accelerated Machine Learning Library. Contribute to BIDData/BIDMach development by creating an account on GitHub.
- 72Graph for Scala is intended to provide basic graph functionality seamlessly fitting into the Scala Collection Library. Like the well known members of scala.collection, Graph for Scala is an in-memory graph library aiming at editing and traversing graphs, finding cycles etc. in a user-friendly way.
https://github.com/scala-graph/scala-graph
Graph for Scala is intended to provide basic graph functionality seamlessly fitting into the Scala Collection Library. Like the well known members of scala.collection, Graph for Scala is an in-memo...
- 73Axle Domain Specific Language for Scientific Cloud Computing and Visualization
https://github.com/axlelang/axle
Axle Domain Specific Language for Scientific Cloud Computing and Visualization - axlelang/axle
- 74Lightweight and fast serialization library for Scala 2/3 based on Protocol Buffers with macros
https://github.com/zero-deps/proto
Lightweight and fast serialization library for Scala 2/3 based on Protocol Buffers with macros - zero-deps/proto
- 75Scala Uniquely Bound Classes Under Traits
https://github.com/dickwall/subcut
Scala Uniquely Bound Classes Under Traits. Contribute to dickwall/subcut development by creating an account on GitHub.
- 76Highly available distributed strong eventual consistent and sequentially consistent storage with feeds, sorting and search
https://github.com/zero-deps/kvs
Highly available distributed strong eventual consistent and sequentially consistent storage with feeds, sorting and search - zero-deps/kvs
- 77Single Page Applications running on the server side.
https://github.com/fomkin/korolev
Single Page Applications running on the server side. - fomkin/korolev
- 78A foundational framework for distributed programming.
https://github.com/reactors-io/reactors
A foundational framework for distributed programming. - reactors-io/reactors
- 79A dimensional analysis library based on dependent types
https://github.com/to-ithaca/libra
A dimensional analysis library based on dependent types - to-ithaca/libra
- 80CSV handling library for Scala
https://github.com/nrinaudo/kantan.csv
CSV handling library for Scala. Contribute to nrinaudo/kantan.csv development by creating an account on GitHub.
- 81MessagePack serializer implementation for Scala / msgpack.org[Scala]
https://github.com/msgpack/msgpack-scala
MessagePack serializer implementation for Scala / msgpack.org[Scala] - msgpack/msgpack-scala
- 82uPickle: a simple, fast, dependency-free JSON & Binary (MessagePack) serialization library for Scala
https://github.com/com-lihaoyi/upickle
uPickle: a simple, fast, dependency-free JSON & Binary (MessagePack) serialization library for Scala - com-lihaoyi/upickle
- 83a simple Scala CLI parsing library
https://github.com/scallop/scallop
a simple Scala CLI parsing library. Contribute to scallop/scallop development by creating an account on GitHub.
- 84Add-on module for Jackson (https://github.com/FasterXML/jackson) to support Scala-specific datatypes
https://github.com/FasterXML/jackson-module-scala
Add-on module for Jackson (https://github.com/FasterXML/jackson) to support Scala-specific datatypes - FasterXML/jackson-module-scala
- 85Type-safe data migration tool for Slick, Git and beyond.
https://github.com/lastland/scala-forklift
Type-safe data migration tool for Slick, Git and beyond. - lastland/scala-forklift
- 86A tidy SQL-based DB access library for Scala developers. This library naturally wraps JDBC APIs and provides you easy-to-use APIs.
https://github.com/scalikejdbc/scalikejdbc
A tidy SQL-based DB access library for Scala developers. This library naturally wraps JDBC APIs and provides you easy-to-use APIs. - scalikejdbc/scalikejdbc
- 87Scala compiler plugin that acts like GNU xgettext command to extract i18n strings in Scala source code files to Gettext .po file
https://github.com/xitrum-framework/scala-xgettext
Scala compiler plugin that acts like GNU xgettext command to extract i18n strings in Scala source code files to Gettext .po file - xitrum-framework/scala-xgettext
- 88REScala - distributed and reactive programming embedded in OO and FP programs.
https://github.com/rescala-lang/REScala
REScala - distributed and reactive programming embedded in OO and FP programs. - rescala-lang/REScala
- 89Scala classpath scanner
https://github.com/xitrum-framework/sclasner
Scala classpath scanner. Contribute to xitrum-framework/sclasner development by creating an account on GitHub.
- 90Iteratees for Cats
https://github.com/travisbrown/iteratee
Iteratees for Cats. Contribute to travisbrown/iteratee development by creating an account on GitHub.
- 91Fast, secure JSON library with tight ZIO integration.
https://github.com/zio/zio-json
Fast, secure JSON library with tight ZIO integration. - zio/zio-json
- 92Schema registry for CSV, TSV, JSON, AVRO and Parquet schema. Supports schema inference and GraphQL API.
https://github.com/indix/schemer
Schema registry for CSV, TSV, JSON, AVRO and Parquet schema. Supports schema inference and GraphQL API. - indix/schemer
- 93Play2.x Authentication and Authorization module
https://github.com/t2v/play2-auth
Play2.x Authentication and Authorization module. Contribute to t2v/play2-auth development by creating an account on GitHub.
- 94Jawn is for parsing jay-sawn (JSON)
https://github.com/typelevel/jawn
Jawn is for parsing jay-sawn (JSON). Contribute to typelevel/jawn development by creating an account on GitHub.
- 95An ONNX (Open Neural Network eXchange) API and backend for typeful, functional deep learning and classical machine learning in Scala 3
https://github.com/EmergentOrder/onnx-scala
An ONNX (Open Neural Network eXchange) API and backend for typeful, functional deep learning and classical machine learning in Scala 3 - EmergentOrder/onnx-scala
- 96Labeled records for Scala based on structural refinement types and macros.
https://github.com/scala-records/scala-records
Labeled records for Scala based on structural refinement types and macros. - scala-records/scala-records
- 97Breeze is a numerical processing library for Scala.
https://github.com/scalanlp/breeze
Breeze is a numerical processing library for Scala. - scalanlp/breeze
- 98Scala Library for Reading Flat File Data (CSV/TSV/XLS/XLSX)
https://github.com/frugalmechanic/fm-flatfile
Scala Library for Reading Flat File Data (CSV/TSV/XLS/XLSX) - frugalmechanic/fm-flatfile
- 99Platform to build distributed, scalable, enterprise-wide business applications
https://github.com/annetteplatform/annette
Platform to build distributed, scalable, enterprise-wide business applications - annetteplatform/annette
- 100Cassovary is a simple big graph processing library for the JVM
https://github.com/twitter/cassovary
Cassovary is a simple big graph processing library for the JVM - twitter/cassovary
- 101A concurrent reactive programming framework.
https://github.com/storm-enroute/reactors
A concurrent reactive programming framework. Contribute to storm-enroute/reactors development by creating an account on GitHub.
- 102Library to register and lookup actors by names in an Akka cluster
https://github.com/xitrum-framework/glokka
Library to register and lookup actors by names in an Akka cluster - xitrum-framework/glokka
- 103:cake: doddle-model: machine learning in Scala.
https://github.com/picnicml/doddle-model
:cake: doddle-model: machine learning in Scala. Contribute to picnicml/doddle-model development by creating an account on GitHub.
- 104A Scala API for Apache Beam and Google Cloud Dataflow.
https://github.com/spotify/scio
A Scala API for Apache Beam and Google Cloud Dataflow. - spotify/scio
- 105A mini Scala utility library
https://github.com/scala-hamsters/hamsters
A mini Scala utility library. Contribute to scala-hamsters/hamsters development by creating an account on GitHub.
- 106Powerful new number types and numeric abstractions for Scala.
https://github.com/typelevel/spire
Powerful new number types and numeric abstractions for Scala. - typelevel/spire
- 107A Persistence Framework for Scala and NoSQL
https://github.com/longevityframework/longevity
A Persistence Framework for Scala and NoSQL. Contribute to longevityframework/longevity development by creating an account on GitHub.
- 108Async lightweight Scala web framework
https://github.com/dvarelap/peregrine
Async lightweight Scala web framework. Contribute to dvarelap/peregrine development by creating an account on GitHub.
- 109CSV Reader/Writer for Scala
https://github.com/tototoshi/scala-csv
CSV Reader/Writer for Scala. Contribute to tototoshi/scala-csv development by creating an account on GitHub.
- 110A Thrift parser/generator
https://github.com/twitter/scrooge
A Thrift parser/generator. Contribute to twitter/scrooge development by creating an account on GitHub.
- 111N-dimensional / multi-dimensional arrays (tensors) in Scala 3. Think NumPy ndarray / PyTorch Tensor but type-safe over shapes, array/axis labels & numeric data types
https://github.com/SciScala/NDScala
N-dimensional / multi-dimensional arrays (tensors) in Scala 3. Think NumPy ndarray / PyTorch Tensor but type-safe over shapes, array/axis labels & numeric data types - SciScala/NDScala
- 112A JSR-310 port of nscala_time
https://github.com/chronoscala/chronoscala
A JSR-310 port of nscala_time. Contribute to chronoscala/chronoscala development by creating an account on GitHub.
- 113Lightweight Scala Dependency Injection Library
https://github.com/scaldi/scaldi
Lightweight Scala Dependency Injection Library. Contribute to scaldi/scaldi development by creating an account on GitHub.
- 114A fault tolerant, protocol-agnostic RPC system
https://github.com/twitter/finagle
A fault tolerant, protocol-agnostic RPC system. Contribute to twitter/finagle development by creating an account on GitHub.
- 115Scala library for accessing various file, batch systems, job schedulers and grid middlewares.
https://github.com/openmole/gridscale
Scala library for accessing various file, batch systems, job schedulers and grid middlewares. - openmole/gridscale
- 116JVM - Java, Kotlin, Scala image processing library
https://github.com/sksamuel/scrimage
JVM - Java, Kotlin, Scala image processing library - sksamuel/scrimage
- 117A group of neural-network libraries for functional and mainstream languages
https://github.com/mrdimosthenis/Synapses
A group of neural-network libraries for functional and mainstream languages - mrdimosthenis/Synapses
- 118Alpakka Kafka connector - Alpakka is a Reactive Enterprise Integration library for Java and Scala, based on Reactive Streams and Akka.
https://github.com/akka/alpakka-kafka
Alpakka Kafka connector - Alpakka is a Reactive Enterprise Integration library for Java and Scala, based on Reactive Streams and Akka. - akka/alpakka-kafka
- 119Productivity-oriented collection of lightweight fancy stuff for Scala toolchain
https://github.com/7mind/izumi
Productivity-oriented collection of lightweight fancy stuff for Scala toolchain - 7mind/izumi
- 120Real Time Analytics and Data Pipelines based on Spark Streaming
https://github.com/Stratio/sparta
Real Time Analytics and Data Pipelines based on Spark Streaming - Stratio/sparta
- 121C4E, a JVM friendly library written in Scala for both local and distributed (Spark) Clustering.
https://github.com/Clustering4Ever/Clustering4Ever
C4E, a JVM friendly library written in Scala for both local and distributed (Spark) Clustering. - Clustering4Ever/Clustering4Ever
- 122Scala extensions for Google Guice
https://github.com/codingwell/scala-guice
Scala extensions for Google Guice. Contribute to codingwell/scala-guice development by creating an account on GitHub.
- 123Purely functional genetic algorithms for multi-objective optimisation
https://github.com/openmole/mgo
Purely functional genetic algorithms for multi-objective optimisation - openmole/mgo
- 124A composable command-line parser for Scala.
https://github.com/bkirwi/decline
A composable command-line parser for Scala. Contribute to bkirwi/decline development by creating an account on GitHub.
- 125ABANDONED Pure Scala serialization library with annotations
https://github.com/fomkin/pushka
ABANDONED Pure Scala serialization library with annotations - fomkin/pushka
- 126Modify deeply nested case class fields
https://github.com/softwaremill/quicklens
Modify deeply nested case class fields. Contribute to softwaremill/quicklens development by creating an account on GitHub.
- 127Non-blocking, ultra-fast Scala Redis client built on top of Akka IO, used in production at Livestream
https://github.com/Livestream/scredis
Non-blocking, ultra-fast Scala Redis client built on top of Akka IO, used in production at Livestream - Livestream/scredis
- 128RxScala – Reactive Extensions for Scala – a library for composing asynchronous and event-based programs using observable sequences
https://github.com/ReactiveX/RxScala
RxScala – Reactive Extensions for Scala – a library for composing asynchronous and event-based programs using observable sequences - ReactiveX/RxScala
- 129Asynchronous, Reactive Programming for Scala and Scala.js.
https://github.com/monix/monix
Asynchronous, Reactive Programming for Scala and Scala.js. - monix/monix
- 130Easy way to create Free Monad using Scala macros with first-class Intellij support.
https://github.com/Thangiee/Freasy-Monad
Easy way to create Free Monad using Scala macros with first-class Intellij support. - Thangiee/Freasy-Monad
- 131Eff monad for cats - https://atnos-org.github.io/eff
https://github.com/atnos-org/eff
Eff monad for cats - https://atnos-org.github.io/eff - atnos-org/eff
- 132The missing MatPlotLib for Scala + Spark
https://github.com/vegas-viz/Vegas
The missing MatPlotLib for Scala + Spark. Contribute to vegas-viz/Vegas development by creating an account on GitHub.
- 133Scala extensions for the Kryo serialization library
https://github.com/twitter/chill
Scala extensions for the Kryo serialization library - twitter/chill
- 134Minimal, type-safe RPC Scala library.
https://github.com/yakivy/poppet
Minimal, type-safe RPC Scala library. Contribute to yakivy/poppet development by creating an account on GitHub.
- 135Reactive Microservices for the JVM
https://github.com/lagom/lagom
Reactive Microservices for the JVM. Contribute to lagom/lagom development by creating an account on GitHub.
- 136A scala extension for Project Reactor's Flux and Mono
https://github.com/spring-attic/reactor-scala-extensions
A scala extension for Project Reactor's Flux and Mono - spring-attic/reactor-scala-extensions
- 137Scala testing library with actionable errors and extensible APIs
https://github.com/scalameta/munit
Scala testing library with actionable errors and extensible APIs - scalameta/munit
- 138Scala wrapper for SnakeYAML
https://github.com/jcazevedo/moultingyaml
Scala wrapper for SnakeYAML. Contribute to jcazevedo/moultingyaml development by creating an account on GitHub.
- 139SynapseGrid is a framework for constructing dynamic low latency data flow systems.
https://github.com/Primetalk/SynapseGrid
SynapseGrid is a framework for constructing dynamic low latency data flow systems. - Primetalk/SynapseGrid
- 140Distributed NoSQL Database
https://github.com/stephenmcd/curiodb
Distributed NoSQL Database. Contribute to stephenmcd/curiodb development by creating an account on GitHub.
- 141Abstract Algebra for Scala
https://github.com/twitter/algebird
Abstract Algebra for Scala. Contribute to twitter/algebird development by creating an account on GitHub.
- 142Spark package to "plug" holes in data using SQL based rules ⚡️ 🔌
https://github.com/indix/sparkplug
Spark package to "plug" holes in data using SQL based rules ⚡️ 🔌 - GitHub - indix/sparkplug: Spark package to "plug" holes in data using SQL based rules ⚡️ 🔌
- 143A simple testing framework for Scala
https://github.com/com-lihaoyi/utest
A simple testing framework for Scala. Contribute to com-lihaoyi/utest development by creating an account on GitHub.
- 144Scalable Image Analysis and Shape Modelling
https://github.com/unibas-gravis/scalismo
Scalable Image Analysis and Shape Modelling. Contribute to unibas-gravis/scalismo development by creating an account on GitHub.
- 145Web-based notebook that enables data-driven, interactive data analytics and collaborative documents with SQL, Scala and more.
https://github.com/apache/zeppelin
Web-based notebook that enables data-driven, interactive data analytics and collaborative documents with SQL, Scala and more. - apache/zeppelin
- 146Mutation testing for Scala
https://github.com/stryker-mutator/stryker4s
Mutation testing for Scala. Contribute to stryker-mutator/stryker4s development by creating an account on GitHub.
- 147Streaming MapReduce with Scalding and Storm
https://github.com/twitter/summingbird
Streaming MapReduce with Scalding and Storm. Contribute to twitter/summingbird development by creating an account on GitHub.
- 148A library that toggles Scala code at compile-time, like #if in C/C++
https://github.com/ThoughtWorksInc/enableIf.scala
A library that toggles Scala code at compile-time, like #if in C/C++ - ThoughtWorksInc/enableIf.scala
- 149Casbah is now officially end-of-life (EOL).
https://github.com/mongodb/casbah
Casbah is now officially end-of-life (EOL). Contribute to mongodb/casbah development by creating an account on GitHub.
- 150Build highly concurrent, distributed, and resilient message-driven applications on the JVM
https://github.com/akka/akka
Build highly concurrent, distributed, and resilient message-driven applications on the JVM - akka/akka
- 151A framework to create embedded Domain-Specific Languages in Scala
https://github.com/ThoughtWorksInc/Dsl.scala
A framework to create embedded Domain-Specific Languages in Scala - ThoughtWorksInc/Dsl.scala
- 152Scala library for boilerplate-free, type-safe data transformations
https://github.com/scalalandio/chimney
Scala library for boilerplate-free, type-safe data transformations - scalalandio/chimney
- 153Interactive and Reactive Data Science using Scala and Spark.
https://github.com/spark-notebook/spark-notebook
Interactive and Reactive Data Science using Scala and Spark. - spark-notebook/spark-notebook
- 154TensorFlow API for the Scala Programming Language
https://github.com/eaplatanios/tensorflow_scala
TensorFlow API for the Scala Programming Language. Contribute to eaplatanios/tensorflow_scala development by creating an account on GitHub.
- 155numsca is numpy for scala
https://github.com/botkop/numsca
numsca is numpy for scala. Contribute to botkop/numsca development by creating an account on GitHub.
- 156A cohesive & pragmatic framework of FP centric Scala libraries
https://github.com/frees-io/freestyle
A cohesive & pragmatic framework of FP centric Scala libraries - frees-io/freestyle
- 157Build software better, together
https://github.com/Sciss/ScalaCollider
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 158A lightweight, clean and simple JSON implementation in Scala
https://github.com/spray/spray-json
A lightweight, clean and simple JSON implementation in Scala - spray/spray-json
- 159A new Scala wrapper for Joda Time based on scala-time
https://github.com/nscala-time/nscala-time
A new Scala wrapper for Joda Time based on scala-time - nscala-time/nscala-time
- 160Convenient and performant logging library for Scala wrapping SLF4J.
https://github.com/lightbend-labs/scala-logging
Convenient and performant logging library for Scala wrapping SLF4J. - lightbend-labs/scala-logging
- 161Blindsight is a Scala logging API with DSL based structured logging, fluent logging, semantic logging, flow logging, and context aware logging.
https://github.com/tersesystems/blindsight
Blindsight is a Scala logging API with DSL based structured logging, fluent logging, semantic logging, flow logging, and context aware logging. - tersesystems/blindsight
- 162Command Line Interface Scala Toolkit
https://github.com/backuity/clist
Command Line Interface Scala Toolkit. Contribute to backuity/clist development by creating an account on GitHub.
- 163command line options parsing for Scala
https://github.com/scopt/scopt
command line options parsing for Scala. Contribute to scopt/scopt development by creating an account on GitHub.
- 164Schema safe, type-safe, reactive Scala driver for Cassandra/Datastax Enterprise
https://github.com/outworkers/phantom
Schema safe, type-safe, reactive Scala driver for Cassandra/Datastax Enterprise - outworkers/phantom
- 165A Scala API for Cascading
https://github.com/twitter/scalding
A Scala API for Cascading. Contribute to twitter/scalding development by creating an account on GitHub.
- 166The fastest logging library in the world. Built from scratch in Scala and programmatically configurable.
https://github.com/outr/scribe
The fastest logging library in the world. Built from scratch in Scala and programmatically configurable. - outr/scribe
- 167State of the Art Natural Language Processing
https://github.com/JohnSnowLabs/spark-nlp
State of the Art Natural Language Processing. Contribute to JohnSnowLabs/spark-nlp development by creating an account on GitHub.
- 168Essential Building Blocks for Scala
https://github.com/wvlet/airframe
Essential Building Blocks for Scala. Contribute to wvlet/airframe development by creating an account on GitHub.
- 169ZIO — A type-safe, composable library for async and concurrent programming in Scala
https://github.com/zio/zio
ZIO — A type-safe, composable library for async and concurrent programming in Scala - zio/zio
- 170Lightweight, modular, and extensible library for functional programming.
https://github.com/typelevel/cats
Lightweight, modular, and extensible library for functional programming. - typelevel/cats
- 171Scala validation library
https://github.com/jap-company/fields
Scala validation library. Contribute to jap-company/fields development by creating an account on GitHub.
- 172Cask: a Scala HTTP micro-framework
https://github.com/com-lihaoyi/cask
Cask: a Scala HTTP micro-framework. Contribute to com-lihaoyi/cask development by creating an account on GitHub.
- 173Slick extensions for PostgreSQL
https://github.com/tminglei/slick-pg
Slick extensions for PostgreSQL. Contribute to tminglei/slick-pg development by creating an account on GitHub.
- 174First class syntax support for type classes in Scala
https://github.com/typelevel/simulacrum
First class syntax support for type classes in Scala - typelevel/simulacrum
- 175Persist-Json, a Fast Json Parser Written in Scala
https://github.com/nestorpersist/json
Persist-Json, a Fast Json Parser Written in Scala. Contribute to nestorpersist/json development by creating an account on GitHub.
- 176Refinement types for Scala
https://github.com/fthomas/refined
Refinement types for Scala. Contribute to fthomas/refined development by creating an account on GitHub.
- 177Generic programming for Scala
https://github.com/milessabin/shapeless
Generic programming for Scala. Contribute to milessabin/shapeless development by creating an account on GitHub.
- 178Lift Framework
https://github.com/lift/framework
Lift Framework. Contribute to lift/framework development by creating an account on GitHub.
- 179Fast, testable, Scala services built on TwitterServer and Finagle
https://github.com/twitter/finatra
Fast, testable, Scala services built on TwitterServer and Finagle - twitter/finatra
- 180Build software better, together
https://github.com/wireapp/wire-signals
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 420 million projects.
- 181The Opinionated RabbitMQ Library for Scala and Akka
https://github.com/SpinGo/op-rabbit
The Opinionated RabbitMQ Library for Scala and Akka - SpinGo/op-rabbit
- 182JSON typeclasses that know the difference between null and absent fields
https://github.com/nrktkt/ninny-json
JSON typeclasses that know the difference between null and absent fields - nrktkt/ninny-json
- 183Scala macros for compile-time generation of safe and ultra-fast JSON codecs + circe booster
https://github.com/plokhotnyuk/jsoniter-scala
Scala macros for compile-time generation of safe and ultra-fast JSON codecs + circe booster - plokhotnyuk/jsoniter-scala
- 184LoMRF is an open-source implementation of Markov Logic Networks
https://github.com/anskarl/LoMRF
LoMRF is an open-source implementation of Markov Logic Networks - anskarl/LoMRF
- 185property based testing library for Scala
https://github.com/scalaprops/scalaprops
property based testing library for Scala. Contribute to scalaprops/scalaprops development by creating an account on GitHub.
- 186Yet another JSON library for Scala
https://github.com/circe/circe
Yet another JSON library for Scala. Contribute to circe/circe development by creating an account on GitHub.
- 187Native Scala mocking framework
https://github.com/paulbutcher/ScalaMock
Native Scala mocking framework. Contribute to paulbutcher/ScalaMock development by creating an account on GitHub.
- 188OAuth 2.0 server-side implementation written in Scala
https://github.com/nulab/scala-oauth2-provider
OAuth 2.0 server-side implementation written in Scala - nulab/scala-oauth2-provider
- 189A small, convenient, dependency-free library for command-line argument parsing in Scala
https://github.com/com-lihaoyi/mainargs
A small, convenient, dependency-free library for command-line argument parsing in Scala - com-lihaoyi/mainargs
- 190Scala + Druid: Scruid. A library that allows you to compose queries in Scala, and parse the result back into typesafe classes.
https://github.com/ing-bank/scruid
Scala + Druid: Scruid. A library that allows you to compose queries in Scala, and parse the result back into typesafe classes. - ing-bank/scruid
- 191akka-persistence-gcp-datastore is a journal and snapshot store plugin for akka-persistence using google cloud firestore in datastore mode.
https://github.com/innFactory/akka-persistence-gcp-datastore
akka-persistence-gcp-datastore is a journal and snapshot store plugin for akka-persistence using google cloud firestore in datastore mode. - GitHub - innFactory/akka-persistence-gcp-datastore: akk...
- 192Mirror of Apache Kafka
https://github.com/apache/kafka
Mirror of Apache Kafka. Contribute to apache/kafka development by creating an account on GitHub.
- 193:leaves: Non-blocking, Reactive MongoDB Driver for Scala
https://github.com/ReactiveMongo/ReactiveMongo
:leaves: Non-blocking, Reactive MongoDB Driver for Scala - ReactiveMongo/ReactiveMongo
- 194Scala GraphQL implementation
https://github.com/sangria-graphql/sangria
Scala GraphQL implementation. Contribute to sangria-graphql/sangria development by creating an account on GitHub.
- 195Functional, stream-based CSV processor for Scala
https://github.com/fingo/spata
Functional, stream-based CSV processor for Scala. Contribute to fingo/spata development by creating an account on GitHub.
- 196ActiveRecord-like ORM library for Scala
https://github.com/aselab/scala-activerecord
ActiveRecord-like ORM library for Scala. Contribute to aselab/scala-activerecord development by creating an account on GitHub.
- 197A Future-free Fs2 native pure FP Redis client
https://github.com/laserdisc-io/laserdisc
A Future-free Fs2 native pure FP Redis client. Contribute to laserdisc-io/laserdisc development by creating an account on GitHub.
- 198Scala framework for building beautiful and maintainable web applications.
https://github.com/UdashFramework/udash-core
Scala framework for building beautiful and maintainable web applications. - UdashFramework/udash-core
- 199Main Portal page for the Jackson project
https://github.com/FasterXML/jackson
Main Portal page for the Jackson project. Contribute to FasterXML/jackson development by creating an account on GitHub.
- 200Library to read, analyze, transform and generate Scala programs
https://github.com/scalameta/scalameta
Library to read, analyze, transform and generate Scala programs - scalameta/scalameta
- 201Compositional, streaming I/O library for Scala
https://github.com/typelevel/fs2
Compositional, streaming I/O library for Scala. Contribute to typelevel/fs2 development by creating an account on GitHub.
- 202The Community Maintained High Velocity Web Framework For Java and Scala.
https://github.com/playframework/playframework
The Community Maintained High Velocity Web Framework For Java and Scala. - playframework/playframework
- 203Scala lightweight, type-safe, asynchronous driver for neo4j
https://github.com/neotypes/neotypes
Scala lightweight, type-safe, asynchronous driver for neo4j - GitHub - neotypes/neotypes: Scala lightweight, type-safe, asynchronous driver for neo4j
- 204Type-safe general-cryptography library - https://jmcardon.github.io/tsec/
https://github.com/jmcardon/tsec
Type-safe general-cryptography library - https://jmcardon.github.io/tsec/ - jmcardon/tsec
- 205JSON library
https://github.com/json4s/json4s
JSON library. Contribute to json4s/json4s development by creating an account on GitHub.
- 206Web & mobile client-side akka-http sessions, with optional JWT support
https://github.com/softwaremill/akka-http-session
Web & mobile client-side akka-http sessions, with optional JWT support - softwaremill/akka-http-session
- 207Lightweight and Nonintrusive Scala Dependency Injection Library
https://github.com/softwaremill/macwire
Lightweight and Nonintrusive Scala Dependency Injection Library - softwaremill/macwire
- 208Rings: efficient JVM library for polynomial rings
https://github.com/PoslavskySV/rings
Rings: efficient JVM library for polynomial rings. Contribute to PoslavskySV/rings development by creating an account on GitHub.
- 209Typesafe, purely functional Computational Intelligence
https://github.com/ciren/cilib
Typesafe, purely functional Computational Intelligence - ciren/cilib
- 210An experimental library for Functional Reactive Programming in Scala
https://github.com/lihaoyi/scala.rx
An experimental library for Functional Reactive Programming in Scala - lihaoyi/scala.rx
- 211New ReactiveCouchbase driver using reactive-streams
https://github.com/ReactiveCouchbase/reactivecouchbase-rs-core
New ReactiveCouchbase driver using reactive-streams - ReactiveCouchbase/reactivecouchbase-rs-core
- 212Simple, safe and intuitive Scala I/O
https://github.com/pathikrit/better-files
Simple, safe and intuitive Scala I/O. Contribute to pathikrit/better-files development by creating an account on GitHub.
- 213Reactive type-safe Scala driver for SQL databases
https://github.com/outworkers/morpheus
Reactive type-safe Scala driver for SQL databases. Contribute to outworkers/morpheus development by creating an account on GitHub.
- 214Lamma schedule generator for Scala is a professional schedule generation library for periodic schedules like fixed income coupon payment, equity deravitive fixing date generation etc.
https://github.com/maxcellent/lamma
Lamma schedule generator for Scala is a professional schedule generation library for periodic schedules like fixed income coupon payment, equity deravitive fixing date generation etc. - GitHub - m...
- 215Tiny High Performance HTTP Server for Scala
https://github.com/analogweb/analogweb-scala
Tiny High Performance HTTP Server for Scala . Contribute to analogweb/analogweb-scala development by creating an account on GitHub.
- 216A test framework that runs everything in parallel.
https://github.com/disneystreaming/weaver-test
A test framework that runs everything in parallel. - GitHub - disneystreaming/weaver-test: A test framework that runs everything in parallel.
- 217Clickhouse Scala Client with Reactive Streams support
https://github.com/crobox/clickhouse-scala-client
Clickhouse Scala Client with Reactive Streams support - crobox/clickhouse-scala-client
- 218Memcached client for Scala
https://github.com/monix/shade
Memcached client for Scala. Contribute to monix/shade development by creating an account on GitHub.
- 219A schema-aware Scala library for data transformation
https://github.com/galliaproject/gallia-core
A schema-aware Scala library for data transformation - galliaproject/gallia-core
- 220Efficient CBOR and JSON (de)serialization in Scala
https://github.com/sirthias/borer
Efficient CBOR and JSON (de)serialization in Scala - sirthias/borer
- 221A purely functional Scala client for CouchDB
https://github.com/beloglazov/couchdb-scala
A purely functional Scala client for CouchDB. Contribute to beloglazov/couchdb-scala development by creating an account on GitHub.
- 222The Play JSON library
https://github.com/playframework/play-json
The Play JSON library. Contribute to playframework/play-json development by creating an account on GitHub.
- 223Image comparison by hash codes
https://github.com/poslegm/scala-phash
Image comparison by hash codes. Contribute to poslegm/scala-phash development by creating an account on GitHub.
- 224Avro schema generation and serialization / deserialization for Scala
https://github.com/sksamuel/avro4s
Avro schema generation and serialization / deserialization for Scala - sksamuel/avro4s
- 225Scala combinator library for working with binary data
https://github.com/scodec/scodec
Scala combinator library for working with binary data - scodec/scodec
- 226Minimal, idiomatic, customizable validation Scala library.
https://github.com/yakivy/dupin
Minimal, idiomatic, customizable validation Scala library. - yakivy/dupin
- 227An implementation of an OAuth2 server designed for mocking/testing
https://github.com/zalando-stups/OAuth2-mock-play
An implementation of an OAuth2 server designed for mocking/testing - zalando-stups/OAuth2-mock-play
- 228A type-safe, reflection-free, powerful enumeration implementation for Scala with exhaustive pattern match warnings and helpful integrations.
https://github.com/lloydmeta/enumeratum
A type-safe, reflection-free, powerful enumeration implementation for Scala with exhaustive pattern match warnings and helpful integrations. - lloydmeta/enumeratum
- 229Optics library for Scala
https://github.com/optics-dev/Monocle
Optics library for Scala. Contribute to optics-dev/Monocle development by creating an account on GitHub.
- 230Scala etcd client implementing V3 APIs
https://github.com/mingchuno/etcd4s
Scala etcd client implementing V3 APIs. Contribute to mingchuno/etcd4s development by creating an account on GitHub.
- 231An asynchronous programming facility for Scala
https://github.com/scala/scala-async
An asynchronous programming facility for Scala. Contribute to scala/scala-async development by creating an account on GitHub.
- 232Accord: A sane validation library for Scala
https://github.com/wix/accord
Accord: A sane validation library for Scala. Contribute to wix-incubator/accord development by creating an account on GitHub.
- 233A data access library for Scala + Postgres.
https://github.com/tpolecat/skunk
A data access library for Scala + Postgres. Contribute to typelevel/skunk development by creating an account on GitHub.
- 234tinylog is a lightweight logging framework for Java, Kotlin, Scala, and Android
https://github.com/tinylog-org/tinylog
tinylog is a lightweight logging framework for Java, Kotlin, Scala, and Android - tinylog-org/tinylog
- 235A purely functional library to build distributed and event-driven systems
https://github.com/parapet-io/parapet
A purely functional library to build distributed and event-driven systems - parapet-io/parapet
- 236Non-blocking, Reactive Redis driver for Scala (with Sentinel support)
https://github.com/etaty/rediscala
Non-blocking, Reactive Redis driver for Scala (with Sentinel support) - etaty/rediscala
- 237Wonderful reusable code from Twitter
https://github.com/twitter/util
Wonderful reusable code from Twitter. Contribute to twitter/util development by creating an account on GitHub.
- 238The Scala API for Quantities, Units of Measure and Dimensional Analysis
https://github.com/typelevel/squants
The Scala API for Quantities, Units of Measure and Dimensional Analysis - typelevel/squants
- 239Squid – type-safe metaprogramming and compilation framework for Scala
https://github.com/epfldata/squid
Squid – type-safe metaprogramming and compilation framework for Scala - epfldata/squid
- 240Principled Functional Programming in Scala
https://github.com/scalaz/scalaz
Principled Functional Programming in Scala. Contribute to scalaz/scalaz development by creating an account on GitHub.
- 241sbt plugin that generates Scala case classes for easy, statically typed and implicit access of JSON data e.g. from API responses
https://github.com/battermann/sbt-json
sbt plugin that generates Scala case classes for easy, statically typed and implicit access of JSON data e.g. from API responses - battermann/sbt-json
- 242Accelerate local LLM inference and finetuning (LLaMA, Mistral, ChatGLM, Qwen, Baichuan, Mixtral, Gemma, Phi, MiniCPM, etc.) on Intel CPU and GPU (e.g., local PC with iGPU, discrete GPU such as Arc, Flex and Max); seamlessly integrate with llama.cpp, Ollama, HuggingFace, LangChain, LlamaIndex, GraphRAG, DeepSpeed, vLLM, FastChat, Axolotl, etc.
https://github.com/intel-analytics/BigDL
Accelerate local LLM inference and finetuning (LLaMA, Mistral, ChatGLM, Qwen, Baichuan, Mixtral, Gemma, Phi, MiniCPM, etc.) on Intel CPU and GPU (e.g., local PC with iGPU, discrete GPU such as Arc,...
- 243Mockito for Scala language
https://github.com/mockito/mockito-scala
Mockito for Scala language. Contribute to mockito/mockito-scala development by creating an account on GitHub.
- 244High-performance SLF4J wrapper for Scala.
https://github.com/Log4s/log4s
High-performance SLF4J wrapper for Scala. Contribute to Log4s/log4s development by creating an account on GitHub.
- 245🔍 Elasticsearch Scala Client - Reactive, Non Blocking, Type Safe, HTTP Client
https://github.com/sksamuel/elastic4s
🔍 Elasticsearch Scala Client - Reactive, Non Blocking, Type Safe, HTTP Client - Philippus/elastic4s
- 246aossie / Agora · GitLab
https://gitlab.com/aossie/Agora/
An Electronic Voting Library implemented in Scala
- 247aossie / Scavenger · GitLab
https://gitlab.com/aossie/Scavenger
A theorem prover based on the conflict resolution calculus
- 248SBT plugin for tweaking various IDE settings
https://github.com/JetBrains/sbt-ide-settings
SBT plugin for tweaking various IDE settings. Contribute to JetBrains/sbt-ide-settings development by creating an account on GitHub.
- 249An HTTP Server and Client library for Scala.
https://github.com/criteo/lolhttp
An HTTP Server and Client library for Scala. Contribute to criteo/lolhttp development by creating an account on GitHub.
- 250Scalafmt · Code formatter for Scala
https://scalameta.org/scalafmt/
Code formatter for Scala
- 251sbt plugin that can check Maven and Ivy repositories for dependency updates
https://github.com/rtimush/sbt-updates
sbt plugin that can check Maven and Ivy repositories for dependency updates - rtimush/sbt-updates
- 252Scala command-line wrapper around ffmpeg, ffprobe, ImageMagick, and other tools relating to media.
https://github.com/outr/media4s
Scala command-line wrapper around ffmpeg, ffprobe, ImageMagick, and other tools relating to media. - outr/media4s
- 253friendly little parsers
https://github.com/tpolecat/atto
friendly little parsers. Contribute to tpolecat/atto development by creating an account on GitHub.
- 254simple combinator-based parsing for Scala. formerly part of the Scala standard library, now a separate community-maintained module
https://github.com/scala/scala-parser-combinators
simple combinator-based parsing for Scala. formerly part of the Scala standard library, now a separate community-maintained module - scala/scala-parser-combinators
Related Articlesto learn about angular.
- 1Introduction to Scala: Beginner’s Guide
- 2Understanding Scala’s Type System: Types and Generics
- 3Functional Programming with Scala
- 4Advanced Functional Programming in Scala: Monads, Functors, and More
- 5Building RESTful APIs with Scala and Akka HTTP: A Beginner’s Guide
- 6Play Framework for Scala Web Development: A Step-by-Step Guide
- 7Concurrency in Scala: Mastering Futures and Promises
- 8Optimizing Scala Performance: Tips for High-Performance Scala Applications
- 9Developing a Scala-based Chat Application: From Concept to Deployment
- 10Creating a Scala-based Data Processing Pipeline: Handling Big Data Efficiently
FAQ'sto learn more about Angular JS.
mail [email protected] to add more queries here 🔍.
- 1
can scala do functional programming
- 2
is scala worth learning in 2023
- 3
is scala popular
- 4
is scala a popular language
- 5
why was scala created
- 6
is scala better than python
- 7
can scala use java libraries
- 8
what is the paradigm of the scala programming language
- 9
why use scala programming language
- 10
should i learn scala
- 11
is scala a good language
- 12
is scala a programming language
- 13
where is la scala opera house located
- 14
when was scala created
- 15
how does scala work
- 16
where is scala installed on windows
- 17
why scala is called functional programming language
- 18
does scala use jvm
- 19
where is scala programming language used
- 20
what is scala software
- 21
why learn scala
- 22
why scala over java
- 23
why scala over python
- 24
- 25
where scala is used
- 26
how to learn scala programming
- 27
is scala a popular programming language
- 28
where is la scala located
- 30
who developed scala
- 31
what is scala code
- 32
why scala is not popular
- 33
- 34
- 35
which of the following programming paradigm does scala support
- 36
- 37
can i use scala code in java
- 38
how is scala different from python
- 39
who created scala
- 40
when scala spark
- 41
is scala dead 2023
- 42
who invented scala
- 43
where is la scala located in italy
- 44
- 45
why scala is functional programming language
- 46
is scala open source
- 47
what is scala mostly used for
- 48
is scala written in java
- 49
is scala a dying language
- 50
what is scala programming language used for
- 51
is scala a good programming language
- 52
why scala is better than java
- 53
what is scala programming
- 54
when to use scala
- 55
can i learn scala without java
- 56
does scala compile to java
- 57
why scala is used
- 58
what is functional programming in scala
- 59
should i learn scala reddit
- 60
should i learn java or scala
- 61
how to pronounce scala programming language
- 63
does scala run on jvm
- 64
what is scala programming used for
- 65
who uses scala programming language
- 66
is scala functional programming
More Sitesto check out once you're finished browsing here.
https://www.0x3d.site/
0x3d is designed for aggregating information.
https://nodejs.0x3d.site/
NodeJS Online Directory
https://cross-platform.0x3d.site/
Cross Platform Online Directory
https://open-source.0x3d.site/
Open Source Online Directory
https://analytics.0x3d.site/
Analytics Online Directory
https://javascript.0x3d.site/
JavaScript Online Directory
https://golang.0x3d.site/
GoLang Online Directory
https://python.0x3d.site/
Python Online Directory
https://swift.0x3d.site/
Swift Online Directory
https://rust.0x3d.site/
Rust Online Directory
https://scala.0x3d.site/
Scala Online Directory
https://ruby.0x3d.site/
Ruby Online Directory
https://clojure.0x3d.site/
Clojure Online Directory
https://elixir.0x3d.site/
Elixir Online Directory
https://elm.0x3d.site/
Elm Online Directory
https://lua.0x3d.site/
Lua Online Directory
https://c-programming.0x3d.site/
C Programming Online Directory
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
https://r-programming.0x3d.site/
R Programming Online Directory
https://perl.0x3d.site/
Perl Online Directory
https://java.0x3d.site/
Java Online Directory
https://kotlin.0x3d.site/
Kotlin Online Directory
https://php.0x3d.site/
PHP Online Directory
https://react.0x3d.site/
React JS Online Directory
https://angular.0x3d.site/
Angular JS Online Directory