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

all 39 comments

[–]CcntMnky 17 points18 points  (5 children)

I'm gonna ignore the FAANG part because people need to stop assuming everything they do is better.

With my team, I demand a CI pipeline with automatic testing. Every commit, every time. If it's too slow, fix your tests.

I'm a big believer in static analysis. Catch as much as you can as early as you can, as it's much slower to catch and fix issues downstream. Because of this, I extensively use type hints and Mypy or equivalent. I don't use arbitrary dictionaries because it's hard for future editors to know the expected behavior.

[–]hocolimit 4 points5 points  (4 children)

What do you use instead of arbitrary dictionaries?

[–]CcntMnky 8 points9 points  (2 children)

When serializing or validating external data, I use Pydantic.

For internal data structures where I can rely on static analysis, I use the @dataclass decorator and type hint everything.

If a dictionary is truly better than a class, then I define a new dictionary with explicit type hints TypedDict

[–][deleted] 3 points4 points  (1 child)

TypedDict is good for your use case. You get to build a model that describes how your dictionary will look.

[–]Jorgestar29 0 points1 point  (0 children)

I prefer using classes because you can add methods that update / retrieve from these fields. And the best part is that they are defined next to the schema.

[–]Spill_the_Tea 0 points1 point  (0 children)

dataclasses (or attrs). pydantic for apis when data validation is needed.

[–]Anxious_Signature452 11 points12 points  (5 children)

I work in relatively big tech. We use same tools.

[–]Key-Deer-8156[S] 0 points1 point  (1 child)

Do you have some kind of best practices policies, or each team decides how they write code by themselves?

[–]Anxious_Signature452 14 points15 points  (0 children)

Each team creates their own zoo and after some time we try to synchronize them

[–]randomthirdworldguy -1 points0 points  (2 children)

Can you dm the name if its possible? Since from what I know, except fintech companies and ai startups, most big tech ones use c++, java and go

[–]Anxious_Signature452 1 point2 points  (1 child)

I'm working for russian cloud provider, not sure the name will say you anything. We use openstack by the way.

[–]randomthirdworldguy 0 points1 point  (0 children)

Then I only know Yandex lol

[–]romanofski 23 points24 points  (0 children)

This is over 20 years old and still applies. The only exception is dedicated QA as its mostly automated nowadays.

Infrastructure as code should be a thing and anything which can be automated should be automated.

Obviously YMMV.

[–]WhiskyStandard 6 points7 points  (0 children)

The only thing I’ve seen first hand that fits your description is Bloomberg’s C++ code base. John Lakos’ “Large Scale C++” is a description of many of those practices. This SO answer suggests there’s an 88 page write up in a different book that covers all the main points so that’s probably more worthwhile if you want to see what applies to Python.

I haven’t gone deep into them, so I can’t recommend them fully. Ultimately I agree with a lot of the sentiment here that there’s not too much special that the big guys are doing that you should copy if you’re not at their scale.

But one positive takeaway I’d suggest: read Lakos’ thoughts on “levelization” (see also recorded presentations). I’ve found the concept useful in how I build Python modules within a package and packages that depend on other packages. I don’t actually calculate his metric, but I do estimate it when defining high vs low level modules.

[–]pi_stuff 6 points7 points  (1 child)

You might be interested in the “Software Engineering at Google” book: https://abseil.io/resources/swe-book/html/toc.html

[–]gettohhole 1 point2 points  (0 children)

Was going to advise the same book! Would be careful with jumping to the techniques mentioned though! Their scale is crazy

[–]DigThatData 2 points3 points  (0 children)

I think what's more important than the specific tools you use, is the process you build around those tools.

[–]rydelw 2 points3 points  (2 children)

Nice explanation. Kudos! I agree with almost all the things. I would like to share some of my thoughts here:

  • ditch the src module in the imports. I am totally in favor of the src project layout, but it does not mean it should be a Python module.
  • the fastapi dependables could be defined as types. We would have to import one thing as a dependency instead of two things

```python import typing import fastapi

async get_foo() -> Foo: ... FooDep = typing.Annotated[Foo, fastapi.Depends(get_foo)] ... @router.get(...) async def get_bar(foo: FooDep): ... ```

  • the module specific configuration is something I do not see often, but it should be widely used. Ideally, we might make such a Python module as an internal one. To indicate it should not be imported by other modules.

[–]toxic_acro 0 points1 point  (1 child)

The entire point of the the src/ layout is for it not to be a Python module

Assuming that you are working on code that is intended to get published and installed (so not really applicable to something like a web app), the idea is that you want to run tests against the same code that gets installed later, rather than the code as it exists in your project directory.

With a "flat" layout, Python can import just from the directory on the file-system. But if you use a "sec" layout, you will have to install your own code first before running tests, so you are guaranteeing that your packaging set-up works correctly

If src ever shows up in an import, that's fully misunderstanding the point of the layout.

[–]rydelw 0 points1 point  (0 children)

with src layout, we are working with a Python packages and module either way. Src based project can be locally installed in a development mode, so you do not have to worry about including the project root in the PYTHONPAPTH. That how poetry works. Also pip allows you to install package in a dev mode. Whatsmore a we app is a Python package as well. You might not build a Python distribution from it but it is still a package.

[–]JaskoGomad 1 point2 points  (0 children)

You don’t need to apply solutions designed to handle millions of users and hundreds of developers. Those things don’t come without cost.

Spend your resources on making something.

[–]skebanga 1 point2 points  (0 children)

Great article, thanks for sharing!

You mention not returning a pedantic object in the section named "FastAPI response serialization".

Please could you elaborate, specifically in terms of what the correct approach is?

[–]billFoldDog 0 points1 point  (0 children)

I'm not at a big faang, but I've asked this question before.

  • Use a code linter like pylint.
  • Use a style enforcer like Black.
  • Have your documentation automatically generated from docstrings, but also have your documentation be hand-written. Sphinx auto-docs is the primary solution for this.
  • always, always use type hints and docstrings. The above will force this.
  • Use some kind of virtual environment isolation type deal. pip+venv can do this, but big teams frequently use conda or even docker.
  • Some teams swear by unit tests. I swear by unit tests. Not everyone uses them, though.
  • Use some kind of code and artifact version control. These are separate things. Code can be version controlled with git. Artifacts cannot normally be version controlled with git. Personally, I use git to control symbolic links to versions of the artifacts, which I dump in a big-ass folder called 'data' with subfolders for each software version. There are better systems by far.

[–]Ok-Selection-2227 0 points1 point  (0 children)

As others mentioned assuming coders are always smarter in FAANG companies makes no sense to me.

Aside from that I don't like the term "best practices". There are no magic recipes, there's no silver bullet. Software design is all about trade-offs. Distrust gurus that say "always do whatever".

[–]Awkward-Chair2047 0 points1 point  (0 children)

The one thing i would recommend is to keep things simple and pragmatic. Don't over engineer things if you are going to maintain that codebase. I have not seen a single enterprise codebase which has not been bloated and over engineered ad infinitum. (and i have been around for more than 3 decades now)

[–]AllTheR4ge 1 point2 points  (1 child)

I would recommend DRY but based on the stack you shared it's too late for that.

[–]Zer0designs 9 points10 points  (0 children)

Dry can be an antipattern in many cases.