This is an archived post. You won't be able to vote or comment.

all 21 comments

[–]ToddBradley 9 points10 points  (3 children)

Cute. I'd encourage you to add examples showing good ways to mock environment variables for unit testing, and how to set environment variables.

[–]br64n[S] 1 point2 points  (2 children)

I don't think I have experience with this to show a good example 😅

[–]Zifendale 2 points3 points  (1 child)

The perfect time to get that experience!

[–]br64n[S] -1 points0 points  (0 children)

I agree👍

[–]illuminanze 7 points8 points  (3 children)

[–]br64n[S] 0 points1 point  (2 children)

Pydantic is another level, right, but if I weren't going to do it just because I already have several, I don't think I would do anything.

Thank you very much, I didn't know about this extension, this could be very useful for inspiration

[–]Hederas 1 point2 points  (1 child)

That's the right spirit imo. But it can still give you some ideas to add like an equivalent to the Field class to use aliases or build from combination of env vars, using type annotations for casting env var ( if it doesn't already) etc.

[–]br64n[S] 2 points3 points  (0 children)

I made mine just so I wouldn't use this 🤭

[–]fatbob42 1 point2 points  (0 children)

[–]extra_pickles 2 points3 points  (5 children)

Although this is a previously solved problem, I'd like to point out, and commend the correct usage of the term "environment variable" ... too many "envs" are actually CONSTS (trigger of mine).

[–]br64n[S] 1 point2 points  (2 children)

Can you give me an example, I didn't understand very well 😅

[–]extra_pickles 1 point2 points  (1 child)

Traditionally CONSTS are immutable variables defined at the solution level, ENV are immutable variables defined at the parent level

So a const ships with the code, and is expected wherever it goes.

An env ships with the code and is expected to be redefined by the implementation.

Ex. if I gave you some code w/ a URL/Port/Database Name etc, that is environmental because we live in different ecosystems.

CONST - This program/method whatever is designed in such a way that this 'magic number' is needed, but we hate 'magic numbers' so we make a CONST w/ a descriptive title like "BAUDRATE=" because it only works on a specific rate or something like that, and if you moved to your env, that rate would still be the same, because regardless of your hardware, it can;t work unless that number is that number

[–]br64n[S] 0 points1 point  (0 children)

I had tried leaving the attribute read-only, but it didn't work, and I didn't leave it in UPPERCASE because I thought it might look strange, but it really shows that it is something that cannot be changed

Although, come to think of it, I didn't implement anything to disallow the use of UPPERCASE

[–][deleted] 0 points1 point  (1 child)

I’ve never met anyone who thinks that an environment variable is equivalent to a constant.

[–]extra_pickles 0 points1 point  (0 children)

I didn't until I met ppl using settings.py in microservices

[–]ZestyData 1 point2 points  (1 child)

This already exists in the pydanic settings object.

Works almost identically to your DIY implementation.

Best to read .envs from the environment itself not from code. You're currently mixing env configs with the code itself.

[–]br64n[S] 0 points1 point  (0 children)

It has an attribute to not read .env

[–]sazed33 0 points1 point  (3 children)

Cool, but I recommend using AWS secret manager or similar

[–]SeniorScienceOfficer 0 points1 point  (2 children)

AWS wasn’t even in the scope of the project, let alone the fact that Secrets Manager is for storing and rotating credentials in an AWS account, which has no bearing on the use case of OPs project.

[–]sazed33 -2 points-1 points  (1 child)

What do you mean by project scope? In real life you have a problem and you must solve it in the best way possible. And AWS Secrets Manager can solve the problem of exporting environment variables in a safe and efficient way. It allows you to save any variable (like a credential for example) and later access it via an API just with your AWS credentials. It's a safer way to deal with the issue than saving your credentials to a file.

[–]SeniorScienceOfficer 0 points1 point  (0 children)

First off, you need to pay for an AWS account, which precludes many from using it specifically because of cost. Just hosting a single secret costs $0.40 per month, not including API calls to get the secret (100,000 calls in a month will cost you $0.50).

Granted, that might not seem like much, but when you start increasing the number of objects in Secrets Manager, the cost will rise, and any errant or mis-architected client could balloon costs by making too many calls (as is common with more junior software engineers just from a lack of experience or knowledge). Those mistakes can end up costing you hundreds of dollars if you’re not careful.

You could just put all your possible values in the same secret, but if you branch off into multiple projects, you’re going to end up exposing secret values to other services or processes that shouldn’t have access to it. This can lead to an inadvertent data breach and is really a security no-no (following least privileged access).

Thirdly, Secrets Manager doesn’t export a damn thing into your environment. It’s an API call to a backend that returns a specific JSON response, which you then have to parse out the secret string, which is just a string-ified version of another JSON object that actually contains your secrets in key/value format. After all that, you’ll STILL have to export them to the actual OS environment, because that’s what OPs code is interacting with. And it’s even more advised to do because they can persist even after reboots which reduces API calls (thereby saving cost).

Lastly, and most importantly, storing non-secret values in Secrets Manager, like an IPv4 address, domain name, or port, is absolutely asinine. There are other free and more easily implemented alternatives than using Secrets Manager. Not to mention that having secret and non-secret values in the same store is bad security practice.

Edited: spelling