{"id":22691544,"url":"https://github.com/rpj/rg","last_synced_at":"2026-05-05T12:33:25.503Z","repository":{"id":40911278,"uuid":"191689006","full_name":"rpj/rg","owner":"rpj","description":"Roentgenium - Rg - The Random Generator.","archived":false,"fork":false,"pushed_at":"2022-12-08T04:39:53.000Z","size":421,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-02-09T06:50:27.137Z","etag":null,"topics":["azure","azure-blob-storage","azure-key-vault","cross-platform","csharp","dotnet","dotnet-core","pipeline","random-generation","randomization","randomizer"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rpj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-06-13T04:08:51.000Z","updated_at":"2023-03-05T00:49:35.000Z","dependencies_parsed_at":"2023-01-24T16:00:15.893Z","dependency_job_id":null,"html_url":"https://github.com/rpj/rg","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rpj/rg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rpj%2Frg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rpj%2Frg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rpj%2Frg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rpj%2Frg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rpj","download_url":"https://codeload.github.com/rpj/rg/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rpj%2Frg/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32649577,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-05T11:29:49.557Z","status":"ssl_error","status_checked_at":"2026-05-05T11:29:48.587Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["azure","azure-blob-storage","azure-key-vault","cross-platform","csharp","dotnet","dotnet-core","pipeline","random-generation","randomization","randomizer"],"created_at":"2024-12-10T01:11:31.235Z","updated_at":"2026-05-05T12:33:25.486Z","avatar_url":"https://github.com/rpj.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Roentgenium - Rg - The Random Generator\n\n## Motivation\n\nA need arose for large, random-but-real-looking data sets and like any proper software developer I immediately took things too far. I also identified - and took advantage of - an opprotunity to learn a lot more about C#'s impressive reflective capabilites.\n\nAs for the name, I'm naturally terrible at naming things so I started simply with just \"Random Generator\". That shortened into \"Rg\" which, thanks to high school chemistry, I'd recalled was a chemical symbol. *Then* I [learned](https://en.wikipedia.org/wiki/Roentgenium) it is extremely radioactive, which of course is one of the best naturally-occuring sources of [true randomness](https://www.fourmilab.ch/hotbits/). So the name stuck.\n\nImplemented as a [.NET Core](https://docs.microsoft.com/en-us/dotnet/core/) [REST API](https://docs.microsoft.com/en-us/aspnet/core/mvc/overview?view=aspnetcore-2.2#web-apis), `Rg` can be built \u0026 run on any major modern OS.\n\n## Building\n\n`dotnet build` in the project directory (the same as in which `Roentgenium.csproj` lives)\n\n### Prerequisities\n\n* [.NET Core 2.2](https://dotnet.microsoft.com/download/dotnet-core/2.2) or later\n\n### Optional\n\n* [Microsoft Azure](https://azure.microsoft.com/) account:\n    * [KeyVault](https://docs.microsoft.com/en-us/azure/key-vault/) can be used to store secrets (such as [connection strings](https://github.com/rpj/rg/blob/master/appsettings.Production.WithAzure.json#L26-L30))\n    * [Blob storage](https://azure.microsoft.com/en-us/services/storage/blobs/) can be [used](https://github.com/rpj/rg/blob/master/appsettings.Production.WithAzure.json#L31-L34) to store the resulting artifacts\n* A Redis instance:\n    * To use the [`stream` output format](#stream-output-format)\n\n## Running\n\n`dotnet run` in the project directory\n* the `ASPNETCORE_ENVIRONMENT` environment variable *directly* controls (via simple substituion) which `appsettings.*.json` file is used *via the interpolation `appsettings.{ASPNETCORE_ENVIRONMENT}.json`).\n\nIn the simplest, default mode, generated data sets will be persisted *only* via the [Filesystem](https://github.com/rpj/rg/blob/master/Stages/Persistence/FilesystemPersistence.cs) persistence module with the artifacts written into the working directory.\n\n### In \"Production\"\n\nThe build artifacts (`Roentgenium.dll` and its brethen in `bin/{CONFIG}/netcoreapp2.2`) are relocatable and can be run directly via the `dotnet` tool by *eliding* (oddly enough) the `run` verb and directly specifiying the `dll` path itself:\n\n* `dotnet bin/Release/netcoreapp2.2/Roentgenium.dll`\n\n`Rg` will always look in the working directory for the appropriate `appsettings` file, so if run directly from the `bin/Release/netcoreapp2.2/` without any settings files, the default configuration (as noted above) will be used.\n\n## Using\n\nFor interface documentation, `Rg` includes [Swagger](https://swagger.io/) self-description support, always accessible on any running instance via the [`/swagger`](http://rg.rpjios.com/swagger) path.\n\n[Postman](https://www.getpostman.com/) is the recommend way to interact easily with the interface.\n\n### `stream` output format\n\nThis output format is implementation-specific to `Rg`, utilizing [Redis](https://redis.io/) [pub/sub](https://redis.io/topics/pubsub) to stream generated data to any number of interested subscribers.\n\nIt requires that the [`Extra`](https://github.com/rpj/rg/blob/master/General/Config.cs#L52-L56) field of the generator configuration structure include an entry [named `streamId`](https://github.com/rpj/rg/blob/master/Stages/Sinks/StreamSink.cs#L19-L25), which specifies the channel name to be used when [publishing](https://redis.io/commands/publish) [each record](https://github.com/rpj/rg/blob/master/Stages/Sinks/StreamSink.cs#L47).\n\n### Demos\n\n* [`rg.rpjios.com`](http://rg.rpjios.com/info) allows larger data sets but does not persist anything to Azure or *currently in any way that is retrievable by the end user!* Best for playing with the [convenience method](https://github.com/rpj/rg/blob/master/Controllers/Generate.cs#L172-L209).\n* [`azure.rg.rpjios.com`](http://azure.rg.rpjios.com/info) only allows small data sets but *does* persist to Azure (per [this configuration](https://github.com/rpj/rg/blob/master/appsettings.Production.WithAzure.json#L25-L36)).\n\n## Extending\n\nThere are many points of extensibility in `Rg` and developers wishing to extend its functionality are encouraged to do so and submit [a PR](https://github.com/rpj/rg/pulls) any time.\n\n### Specifications\n\nLiving [here](https://github.com/rpj/rg/tree/master/Specifications), they're simple serializable classes\nimplementing [`ISpecification`](https://github.com/rpj/rg/blob/master/General/Types.cs#L80) which [are then\nexposed](https://github.com/rpj/rg/blob/master/General/BuiltIns.cs#L43-L50) as the [supported specifications](http://rg.rpjios.com/info/supported/specifications).\n\n### Field generators\n\nFields in an `ISpecification` are generated based on either the [default generator for the field's `Type`](https://github.com/rpj/rg/blob/master/FieldGenerators/DefaultGenerators.cs) or a [custom generator](https://github.com/rpj/rg/blob/master/FieldGenerators/CustomGenerators.cs) specified explicitly per-field via the [`GeneratorTypeAttribute`](https://github.com/rpj/rg/blob/master/General/Attrs.cs#L61-L74).\n\n### Stages\n\nThe general [`IPipeline`](https://github.com/rpj/rg/blob/master/General/Types.cs#L28-L65) interface specifies a feed-forward data pipeline, currently concretely implemented only once by [`Pipeline.cs`](https://github.com/rpj/rg/blob/master/Pipeline/Pipeline.cs).\n\n#### Sources\n\n[`ISourceStage`](https://github.com/rpj/rg/blob/master/General/Types.cs#L82-L100) implementation. There currently is [only one](https://github.com/rpj/rg/blob/master/Stages/Sources/GeneratorSource.cs) which generates random data based on the specification \u0026 any mutating [attributes](https://github.com/rpj/rg/blob/master/General/Attrs.cs) applied, eventually calling the appropriate [field generators](https://github.com/rpj/rg/tree/master/FieldGenerators) to build data sets.\n\nHowever, the source interface only requires implementation of [a single method](https://github.com/rpj/rg/blob/master/General/Types.cs#L88-L99), so adding different sources would be relatively straightforward though would require [addressing](https://github.com/rpj/rg/blob/master/General/Types.cs#L37) [a](https://github.com/rpj/rg/blob/master/General/Types.cs#L83-L84) [few](https://github.com/rpj/rg/blob/master/Pipeline/Pipeline.cs#L77-L78) [assumptions](https://github.com/rpj/rg/blob/master/Pipeline/Pipeline.cs#L135-L136) that there'd only ever be one.\n\nOf note is that the system assumes that any concrete implemenation is capable of [producing infinite `IGeneratedRecord`s](https://github.com/rpj/rg/blob/master/General/Types.cs#L89-L91).\n\n#### Intermediates (\"filters\")\n\n[`IIntermediateStage`](https://github.com/rpj/rg/blob/master/General/Types.cs#L133-L139) implementations which themselves are just both an `ISourceStage` \u0026 `ISinkStage` at once, having each record \"passed through\" during execution of the overall pipeline. They are [enumerated at runtime](https://github.com/rpj/rg/blob/master/General/BuiltIns.cs#L52-L56) to be exposed as the [supported filters](http://rg.rpjios.com/info/supported/filters).\n\n#### Outputs\n\n[`ISinkStage`](https://github.com/rpj/rg/blob/master/General/Types.cs#L104-L131) implementations named according to and with an [`OutputFormatSinkType`](https://github.com/rpj/rg/blob/master/General/Attrs.cs#L37-L42) attribute specified, these stages are [exposed at runtime](https://github.com/rpj/rg/blob/master/General/BuiltIns.cs#L64-L65) as the [available output formats](http://rg.rpjios.com/info/supported/outputs).\n\nThe [`stream`](https://github.com/rpj/rg/blob/master/Stages/Sinks/StreamSink.cs) format implementation does not use the bonafide [`stream`](https://redis.io/topics/streams-intro) data type as it isn't yet widely available.\n\n#### Persistence\n\nImplementations of [`IPersistenceStage`](https://github.com/rpj/rg/blob/master/General/Types.cs#L141-L150), a specialized stage that exists only to persist the otherwise-ephermal results of the pipeline somewhere else.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frpj%2Frg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frpj%2Frg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frpj%2Frg/lists"}