def test_csv(): csv = CommaSeparatedStrings('"localhost", "127.0.0.1", 0.0.0.0') assert list(csv) == ["localhost", "127.0.0.1", "0.0.0.0"] assert repr( csv) == "CommaSeparatedStrings(['localhost', '127.0.0.1', '0.0.0.0'])" assert str(csv) == "'localhost', '127.0.0.1', '0.0.0.0'" assert csv[0] == "localhost" assert len(csv) == 3 csv = CommaSeparatedStrings("'localhost', '127.0.0.1', 0.0.0.0") assert list(csv) == ["localhost", "127.0.0.1", "0.0.0.0"] assert repr( csv) == "CommaSeparatedStrings(['localhost', '127.0.0.1', '0.0.0.0'])" assert str(csv) == "'localhost', '127.0.0.1', '0.0.0.0'" csv = CommaSeparatedStrings("localhost, 127.0.0.1, 0.0.0.0") assert list(csv) == ["localhost", "127.0.0.1", "0.0.0.0"] assert repr( csv) == "CommaSeparatedStrings(['localhost', '127.0.0.1', '0.0.0.0'])" assert str(csv) == "'localhost', '127.0.0.1', '0.0.0.0'" csv = CommaSeparatedStrings(["localhost", "127.0.0.1", "0.0.0.0"]) assert list(csv) == ["localhost", "127.0.0.1", "0.0.0.0"] assert repr( csv) == "CommaSeparatedStrings(['localhost', '127.0.0.1', '0.0.0.0'])" assert str(csv) == "'localhost', '127.0.0.1', '0.0.0.0'"
def __init__(self): #Configuracion Basica self.stage = os.getenv("STAGE", "") self.version = os.getenv("VERSION", "v1") self.project_name = os.getenv("PROJECT_NAME", "Serverless python fastapi") self.project_description = os.getenv( "PROJECT_DESCRIPTION", "Sample project with python and fastapi") #Configuracion Sentry self.dsn_sentry = os.getenv("DSN_SENTRY", "") #Configuracion Cors self.allow_origins = list( CommaSeparatedStrings(os.getenv("ALLOW_ORIGINS", "*"))) self.allow_credentials = os.getenv("ALLOW_CREDENTIALS", "true").lower() == "true".lower() self.allow_methods = list( CommaSeparatedStrings(os.getenv("ALLOW_METHODS", "*"))) self.allow_headers = list( CommaSeparatedStrings(os.getenv("ALLOW_HEADERS", "*"))) #Configuracion recursos externos self.url_todos = os.getenv( "URL_TODOS", "https://jsonplaceholder.typicode.com/todos/1")
def collect_server_settings(ssh_settings): # pragma: no cover from api.schemes import ( ConfiguratorAdvancedSettings, ConfiguratorCoinDescription, ConfiguratorDomainSettings, ConfiguratorServerSettings, ) settings = ConfiguratorServerSettings() try: client = ssh_settings.create_ssh_client() env = ServerEnv(client) cryptos = CommaSeparatedStrings(env.get("BITCART_CRYPTOS", "btc")) for crypto in cryptos: symbol = crypto.upper() network = env.get(f"{symbol}_NETWORK", "mainnet") lightning = str_to_bool(env.get(f"{symbol}_LIGHTNING", "false")) settings.coins[crypto] = ConfiguratorCoinDescription(network=network, lightning=lightning) domain = env.get("BITCART_HOST", "") reverse_proxy = env.get("BITCART_REVERSEPROXY", "nginx-https") is_https = reverse_proxy in constants.HTTPS_REVERSE_PROXIES settings.domain_settings = ConfiguratorDomainSettings(domain=domain, https=is_https) installation_pack = env.get("BITCART_INSTALL", "all") additional_components = list(CommaSeparatedStrings(env.get("BITCART_ADDITIONAL_COMPONENTS", ""))) settings.advanced_settings = ConfiguratorAdvancedSettings( installation_pack=installation_pack, additional_components=additional_components ) client.close() except Exception: pass return settings
async def _create_payment_method(invoice, wallet, product, store, discounts, promocode, lightning=False): coin = settings.get_coin(wallet.currency, wallet.xpub) discount_id = None rate = await coin.rate(invoice.currency) if math.isnan(rate): rate = await coin.rate(store.default_currency) if math.isnan(rate): rate = await coin.rate("USD") if math.isnan(rate): rate = Decimal(1) # no rate available, no conversion price = invoice.price if discounts: try: discount = max( filter( lambda x: (not x.currencies or wallet.currency in CommaSeparatedStrings(x.currencies)) and (promocode == x.promocode or not x.promocode), discounts, ), key=attrgetter("percent"), ) logger.info(f"Payment method {wallet.currency} of invoice {invoice.id}: matched discount {discount.id}") discount_id = discount.id price -= price * (Decimal(discount.percent) / Decimal(100)) except ValueError: # no matched discounts pass request_price = price * ((1 - (Decimal(store.checkout_settings.underpaid_percentage) / 100))) request_price = currency_table.normalize(wallet.currency, request_price / rate) price = currency_table.normalize(wallet.currency, price / rate) method = coin.add_request if lightning: # pragma: no cover try: await coin.node_id # check if works method = coin.add_invoice except errors.LightningUnsupportedError: return recommended_fee = ( await coin.server.recommended_fee(store.checkout_settings.recommended_fee_target_blocks) if not lightning else 0 ) recommended_fee = 0 if recommended_fee is None else recommended_fee # if no rate available, disable it recommended_fee = round_up(Decimal(recommended_fee) / 1024, 2) # convert to sat/byte, two decimal places data_got = await method(request_price, description=product.name if product else "", expire=invoice.expiration) address = data_got["address"] if not lightning else data_got["invoice"] url = data_got["URI"] if not lightning else data_got["invoice"] node_id = await coin.node_id if lightning else None rhash = data_got["rhash"] if lightning else None return await models.PaymentMethod.create( invoice_id=invoice.id, amount=price, rate=rate, discount=discount_id, currency=wallet.currency, payment_address=address, payment_url=url, rhash=rhash, lightning=lightning, node_id=node_id, recommended_fee=recommended_fee, confirmations=0, )
def provide_es_client(self, config: Config) -> Elasticsearch: hosts: CommaSeparatedStrings = config('ES_HOSTS', cast=CommaSeparatedStrings, default=CommaSeparatedStrings( ['http://127.0.0.1:9200'])) client = Elasticsearch(hosts=hosts) LOGGER.debug(fullname(Elasticsearch) + ' configurated') return client
def parse_tags(value: str) -> typing.Dict[str, str]: tags = {} for tag in CommaSeparatedStrings(value): key, sep, val = tag.partition(":") if not sep: raise ValueError(f"Invalid tag format: {tag!r}") assert sep tags[key] = val return tags
class Config: DB_NAME = 'fastapisimple' USERS_DOCUMENT_NAME = 'users' MONGODB_URL = f'mongodb://localhost:27017/{DB_NAME}' DEFAULT_ROUTE_STR = "/api" SECRET_KEY = Secret('a nice secret key') ALLOWED_HOSTS = CommaSeparatedStrings("localhost, 127.0.0.1")
async def update_invoice_payments(invoice, wallets, discounts, task_wallets, store, product, promocode): for wallet_id in wallets: wallet = await models.Wallet.get(wallet_id) if wallet.currency not in invoice.payments: coin = settings.get_coin(wallet.currency, wallet.xpub) discount_id = None price = invoice.price / await coin.rate(invoice.currency, accurate=True) if math.isnan(price): price = invoice.price / await coin.rate(store.default_currency, accurate=True) if math.isnan(price): price = invoice.price / await coin.rate("USD", accurate=True) if math.isnan(price): price = invoice.price if discounts: try: discount = max( filter( lambda x: (not x.currencies or wallet.currency in CommaSeparatedStrings(x.currencies)) and (promocode == x.promocode or not x.promocode), discounts, ), key=attrgetter("percent"), ) discount_id = discount.id price -= price * (Decimal(discount.percent) / Decimal(100)) except ValueError: # no matched discounts pass task_wallets[wallet.currency] = wallet.xpub data_got = await coin.addrequest( str(price), description=product.name if product else "", expire=invoice.expiration) await models.PaymentMethod.create( invoice_id=invoice.id, amount=price, discount=discount_id, currency=wallet.currency, payment_address=data_got["address"], payment_url=data_got["URI"], ) invoice.payments[wallet.currency] = { "payment_address": data_got["address"], "payment_url": data_got["URI"], "amount": price, "discount": discount_id, "currency": wallet.currency, } add_invoice_expiration(invoice) tasks.poll_updates.send(invoice.id, task_wallets)
async def create_invoice(invoice: schemes.CreateInvoice, user: schemes.User): d = invoice.dict() store = await models.Store.get(d["store_id"]) d["currency"] = d["currency"] or store.default_currency or "USD" products = d.get("products", {}) if isinstance(products, list): products = {k: 1 for k in products} promocode = d.get("promocode") d["products"] = list(products.keys()) obj, wallets = await models.Invoice.create(**d) product = None if d["products"]: product = await models.Product.get(d["products"][0]) await product_add_related(product) created = [] for key, value in products.items(): # type: ignore created.append((await models.ProductxInvoice.create(invoice_id=obj.id, product_id=key, count=value)).product_id) obj.products = created obj.payments = {} task_wallets = {} current_date = utils.now() discounts = [] if product: discounts = [ await models.Discount.get(discount_id) for discount_id in product.discounts ] discounts = list(filter(lambda x: current_date <= x.end_date, discounts)) for wallet_id in wallets: wallet = await models.Wallet.get(wallet_id) if not wallet.currency in obj.payments: coin = settings.get_coin(wallet.currency, wallet.xpub) discount_id = None price = obj.price / await coin.rate(obj.currency, accurate=True) if math.isnan(price): price = obj.price / await coin.rate(store.default_currency, accurate=True) if math.isnan(price): price = obj.price / await coin.rate("USD", accurate=True) if math.isnan(price): price = obj.price if discounts: try: discount = max( filter( lambda x: (not x.currencies or wallet.currency in CommaSeparatedStrings(x.currencies)) and (promocode == x.promocode or not x.promocode), discounts, ), key=attrgetter("percent"), ) discount_id = discount.id price -= price * (Decimal(discount.percent) / Decimal(100)) except ValueError: # no matched discounts pass task_wallets[wallet.currency] = wallet.xpub data_got = await coin.addrequest( str(price), description=product.name if product else "") await models.PaymentMethod.create( invoice_id=obj.id, amount=price, discount=discount_id, currency=wallet.currency, payment_address=data_got["address"], payment_url=data_got["URI"], ) obj.payments[wallet.currency] = { "payment_address": data_got["address"], "payment_url": data_got["URI"], "amount": price, "discount": discount_id, "currency": wallet.currency, } tasks.poll_updates.send(obj.id, task_wallets) return obj
import os from dotenv import load_dotenv from starlette.datastructures import CommaSeparatedStrings API_V1_STR = '/api' load_dotenv('.env') api_id = os.getenv('API_ID') api_hash = os.getenv('API_HASH') PROJECT_NAME = os.getenv('PROJECT_NAME', 'FastAPI application with Telegram') ALLOWED_HOSTS = CommaSeparatedStrings(os.getenv('ALLOWED_HOSTS', ''))
from starlette.datastructures import CommaSeparatedStrings from starlette.exceptions import HTTPException from starlette.middleware.cors import CORSMiddleware from starlette.middleware.gzip import GZipMiddleware from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY from app import __version__ from app.core.config import ALLOWED_HOSTS, API_V1_STR, PROJECT_NAME, DEBUG from app.core.errors import http_422_error_handler, http_error_handler from app.db.db_utils import close_mysql_connection, connect_to_mysql from app.http.v1.route import main_router as api_router app = FastAPI(title=PROJECT_NAME, debug=DEBUG, version=__version__) if not ALLOWED_HOSTS: ALLOWED_HOSTS = CommaSeparatedStrings("*") app.add_middleware( CORSMiddleware, allow_origins=ALLOWED_HOSTS, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.add_middleware(GZipMiddleware, minimum_size=100) # app.add_event_handler("startup", connect_to_mysql) # app.add_event_handler("shutdown", close_mysql_connection) app.add_exception_handler(HTTPException, http_error_handler)
KNOWN_DOMAINS = [ "localhost", "florimondmanca.com", "blog.florimondmanca.com", "florimond.dev", "blog.florimond.dev", ] STATIC_ROOT = "/static" STATIC_DIR = HERE / "static" TEMPLATES_DIR = HERE / "templates" EXTRA_CONTENT_DIRS = config( "EXTRA_CONTENT_DIRS", cast=lambda v: [pathlib.Path(item) for item in CommaSeparatedStrings(v)], default="", ) # Images take too much room on the Web. Let's limit ourselves # to reasonable sizes only. IMAGE_ALLOWED_MAX_SIZE_KB = 32 CONTENT_DIR = HERE.parent / "content" with open(HERE / "assets" / "legacy-blog-url-mapping.json") as f: LEGACY_URL_MAPPING = json.loads(f.read()) MARKDOWN_EXTENSIONS = ["codehilite", "fenced_code", "tables", ImageFigcaptions()] SOCIAL_LINKS = [ { "href": "https://github.com/florimondmanca",
import os import pytest import sqlalchemy from starlette.applications import Starlette from starlette.database import transaction from starlette.datastructures import CommaSeparatedStrings, DatabaseURL from starlette.middleware.database import DatabaseMiddleware from starlette.responses import JSONResponse from starlette.testclient import TestClient try: DATABASE_URLS = CommaSeparatedStrings(os.environ["STARLETTE_TEST_DATABASES"]) except KeyError: # pragma: no cover pytest.skip("STARLETTE_TEST_DATABASES is not set", allow_module_level=True) metadata = sqlalchemy.MetaData() notes = sqlalchemy.Table( "notes", metadata, sqlalchemy.Column("id", sqlalchemy.Integer, primary_key=True), sqlalchemy.Column("text", sqlalchemy.String(length=100)), sqlalchemy.Column("completed", sqlalchemy.Boolean), ) @pytest.fixture(autouse=True, scope="module") def create_test_databases(): engines = {}
def parse_tags_from_string(value: str) -> Dict[str, str]: return parse_tags_from_list(CommaSeparatedStrings(value))
from starlette.config import Config from starlette.datastructures import CommaSeparatedStrings, Secret config = Config(".env") MAX_CONNECTIONS_COUNT = int(config("MAX_CONNECTIONS_COUNT", default=10)) MIN_CONNECTIONS_COUNT = int(config("MIN_CONNECTIONS_COUNT", default=10)) SECRET_KEY = Secret(config("SECRET_KEY", default="secret key for project")) PROJECT_NAME = config("PROJECT_NAME", default="FastAPI example application") ALLOWED_HOSTS = CommaSeparatedStrings(config("ALLOWED_HOSTS", default="")) MONGODB_URL = config("DB", default="") # deploying without docker-compose database_name = "shostner" DEFAULT_URL = "http://jlugao.com" ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 30
from starlette.datastructures import CommaSeparatedStrings from starlette.datastructures import Secret logger = logging.getLogger("fastapi boilerplate") logger.setLevel(logging.DEBUG) # Change for production API_V1_STR = "/api/v1" JWT_TOKEN_PREFIX = "Token" ACCESS_TOKEN_EXPIRE_MINUTES = 60 * 24 * 7 # one week SECRET_KEY = Secret(getenv("SECRET_KEY", "secret key for project")) MAX_CONNECTIONS_COUNT = int(getenv("MAX_CONNECTIONS_COUNT", 10)) MIN_CONNECTIONS_COUNT = int(getenv("MIN_CONNECTIONS_COUNT", 10)) PROJECT_NAME = getenv("PROJECT_NAME", "FastAPI example application") ARGO_API_TIMEOUT = 60 ALLOWED_HOSTS = CommaSeparatedStrings(getenv("ALLOWED_HOSTS", "")) MONGO_HOST = getenv("MONGO_HOST") MONGO_PORT = getenv("MONGO_PORT") MONGO_USER = getenv("MONGO_USER") MONGO_PASSWORD = getenv("MONGO_PASSWORD") MONGO_DB = getenv("MONGO_DB") DATABASE_NAME = getenv("MONGO_DB") USERS_COLLECTION_NAME = "users" MONGODB_URI = ( f"mongodb://{MONGO_USER}:{MONGO_PASSWORD}@{MONGO_HOST}:{MONGO_PORT}") RESOURCES_PATH = "app/resources"
""" Project Settings file """ import os from starlette.datastructures import CommaSeparatedStrings, Secret default_route_str = "/api" ALLOWED_HOSTS = CommaSeparatedStrings(os.getenv("ALLOWED_HOSTS", "*")) SECRET_KEY = Secret( os.getenv( "SECRET_KEY", "4bf4f696a653b292bc674daacd25195b93fce08a8dac7373b36c38f63cd442938b12ef911bd5d7d0" )) # Mongo configuration mongo_max_connections = int(os.getenv("MAX_CONNECTIONS_COUNT", 10)) mongo_min_connections = int(os.getenv("MIN_CONNECTIONS_COUNT", 10)) mongo_db = "fastapi" mongo_url = f"mongodb://*****:*****@email.com"
import os from starlette.datastructures import CommaSeparatedStrings # Prefix for API Url API_V1_STR = os.getenv("API_V1_STR", "/api") # Name of projetct do initialize application PROJECT_NAME = os.getenv("PROJECT_NAME", "API") # Allowed hosts for CORS Policy ALLOWED_HOSTS = CommaSeparatedStrings(os.getenv("ALLOWED_HOSTS", '')) or None # Debug projetct DEBUG = bool(os.getenv("DEBUG", False)) PERSONAL_TOKEN = os.getenv("PERSONAL_TOKEN", '')