0

im kind of a newbie so take me easy

i face a problem every time i make a project specially Client projects, which is Global State i always struggle to do it

for example, here is the structure of one of my Project Templates

TelegramBot

data/
  -- settings.py # configs
  -- text.yaml # message handling
plugins/ # telegram SDKs stuff
src/ # this can be "api", "utils", whatever
  helpers/ # sepcific functions to some user flows
  middlewares/ # middlewares, duh
  -- utils.py # functions used all over app
  -- strings.py # uses text.yaml and provides an API for messages
  -- database.py # DB API
  -- step.py # User Prompting API
  -- logger.py # logging

app.py # entry point
.gitignore
(etc, etc)

i always struggle on how to define a Global State or Config which has Database Session, Strings API, Prompting AP

every way i think of it doesn't feel right

one soloution i found is a global main.py files on the src directory

# src/main.py
from database import DB
from step import Step
from strings import Strings
from data.settings import *

db = DB()
step = Step(db)
strings = Strings()

but this has many problems like

What if the step API needed something from the strings API

What if i needed to do circular imports (python)

Why Would i even need to do a circular import?, this does not seem like best practice

and i end with: This Template Sucks (deletes it and start a new one)

is there a BEST or CLEAN way or practice of passing global state into all the project?

im still a new Coder, i have learned python 1 and a half year ago

3
  • 3
    Do not keep configuration in source code. Keep it in a separate data file, json or yaml or xml, or whatever (but not in Python). But separated from the app. Because you don't want to put code there, it just leads to mess. I blame Django for popularizing this anti pattern. Commented Jun 17 at 5:35
  • i see it easier to but it in a source file, because i will import those config files into 1 source file anyways, this is just a simple template, so security isn't a big concern here Commented Jun 17 at 20:16
  • 1
    It's not about security but separation of concerns. You make config a source file, and then people keep adding stuff there. Including file i/o or even network i/o. Because you have Python, then why not? And then you have a mess, for example impossible to develop locally. Do not trust developers if you can enforce good standards. Commented Jun 17 at 20:30

2 Answers 2

5

Work on your dependencies. Then inject concretes at runtime. This is what you are already doing, with your main.py providing the database inject into Steps API, and your don't have any circular dependency here—it would make little sense for the database later to require to access Steps API, for instance.

What if the step API needed something from the strings API?

Be more specific. What would it need?

Let's take an example of a Q&A website. Let's consider that there is a controller that handles everything related to users (creating one, handling login, etc.), and a controller that handles actual questions and answers.

Obviously, questions and answers have authors. But this doesn't mean QAController needs to know anything about UsersController—it doesn't matter how login works, or how new users are registered.

What matters is to be able to map a given user identifier to the name of the person to display in the user interface. But this mapping is not the responsibility of UsersController. It might be a users service. Or something much smaller, that does just that—takes an identifier, returns user information.

In languages such as Java or C# that have a notion of interface, QAController could for example request a dependency such as IUserFinder, that could be implemented by UsersService, given that the service may implement several other interfaces as well. In languages such as Python, your controller may simply require a function to call to get user information from identifier (as opposed to an instance if a class implementing an interface).

One side benefit to (1) depend on abstractions, and especially to (2) depend only on interfaces that are actually being used, is better testability. When unit testing your code, you'll be able to inject mocks instead of business implementations, and you'll able to create small, simple mocks.

Those are, by the way, two of the five SOLID principles: Dependency inversion principle and Interface segregation principle.

2

What if i needed to do circular imports (python)

Why Would i even need to do a circular import?, this does not seem like best practice

This is a limitation of Python but your intuition is good here. Even in languages that support them, they tend to be undesirable. The presence of a circular import, in general, usually indicates a design problem. There are tricks to get around the limitation in Python but IMO, you are better off splitting up modules to eliminate them.

What if the step API needed something from the strings API

And what if it does? What problem are you seeing. Is your strings API confined to calls defined on the Strings class? If so, why? What kind of state does a Strings object manage?

5
  • the What if the step API needed something from the strings API was a random one perhaps let say that the Step API needs a DB session for example, to create the user Step in the database this doesn't feel like a good practice, and violates the SRP bt DB Session here i mean a DB Object Commented Jun 17 at 20:14
  • I'm not sure I follow. Your code example shows the DB object being passed to the Step constructor. Are you saying that you don't think that's right? Commented Jun 17 at 20:49
  • i don't really know anymore, i feel it's bad but how else could i inject that function in Step Commented Jun 18 at 3:30
  • 2
    @PythoonNoob9000 What makes you feel like it is bad? Is there a specific issue you are running into? When you are starting out, you are going to have a lot of problems to figure out and solve. I would recommend focusing on those thing that are getting in your way. Don't worry about getting everything perfect because that will never happen anyway. Commented Jun 18 at 18:29
  • i was just being worried about perfection and best practices maybe i thought this "Template" is bad because TelegramBots making take alot of time and work thank you for advice Commented Jun 19 at 6:06

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.