mainsequence 2.0.2__py3-none-any.whl → 2.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
mainsequence/cli/api.py CHANGED
@@ -155,3 +155,32 @@ def add_deploy_key(project_id: int | str, key_title: str, public_key: str) -> No
155
155
  {"key_title": key_title, "public_key": public_key})
156
156
  except Exception:
157
157
  pass
158
+
159
+ def get_project_token(project_id: int | str) -> str:
160
+ """
161
+ Fetch the project's token using the current access token.
162
+ If the access token is expired or missing, authed() will refresh once.
163
+ If refresh also fails, NotLoggedIn is raised so the caller can prompt re-login.
164
+ """
165
+ r = authed("GET", f"/orm/api/pods/projects/{project_id}/get_project_token/")
166
+ if not r.ok:
167
+ # authed() already tried refresh on 401;
168
+ # at this point treat as API error with server message.
169
+ msg = r.text
170
+ try:
171
+ if r.headers.get("content-type","").startswith("application/json"):
172
+ data = r.json()
173
+ msg = data.get("detail") or data.get("message") or msg
174
+ except Exception:
175
+ pass
176
+ raise ApiError(f"Project token fetch failed ({r.status_code}). {msg}")
177
+
178
+ token = None
179
+ if r.headers.get("content-type","").startswith("application/json"):
180
+ data = r.json()
181
+ token=data["development"]
182
+ if not token:
183
+ token = (r.text or "").strip()
184
+ if not token:
185
+ raise ApiError("Project token response did not include a token.")
186
+ return token[0]
mainsequence/cli/cli.py CHANGED
@@ -26,6 +26,7 @@ from .api import (
26
26
  login as api_login,
27
27
  repo_name_from_git_url,
28
28
  safe_slug,
29
+ get_project_token
29
30
  )
30
31
  from .ssh_utils import (
31
32
  ensure_key_for_repo,
@@ -287,6 +288,7 @@ def project_set_up_locally(
287
288
  cfg_obj = cfg.get_config()
288
289
  base = base_dir or cfg_obj["mainsequence_path"]
289
290
 
291
+
290
292
  org_slug = _org_slug_from_profile()
291
293
 
292
294
  items = get_projects()
@@ -346,8 +348,33 @@ def project_set_up_locally(
346
348
  else:
347
349
  if env_text and not env_text.endswith("\n"): env_text += "\n"
348
350
  env_text += f"VFB_PROJECT_PATH={str(target_dir)}\n"
351
+
352
+ try:
353
+ project_token = get_project_token(project_id)
354
+ except NotLoggedIn:
355
+ typer.secho("Session expired or refresh failed. Run: mainsequence login <email>", fg=typer.colors.RED)
356
+ raise typer.Exit(1)
357
+ except ApiError as e:
358
+ typer.secho(f"Could not fetch project token: {e}", fg=typer.colors.RED)
359
+ raise typer.Exit(1)
360
+
361
+ lines = env_text.splitlines()
362
+ if any(line.startswith("MAINSEQUENCE_TOKEN=") for line in lines):
363
+ lines = [
364
+ (f"MAINSEQUENCE_TOKEN={project_token}" if line.startswith("MAINSEQUENCE_TOKEN=") else line)
365
+ for line in lines
366
+ ]
367
+ env_text = "\n".join(lines)
368
+ else:
369
+ if env_text and not env_text.endswith("\n"): env_text += "\n"
370
+ env_text += f"MAINSEQUENCE_TOKEN={project_token}\n"
371
+
372
+ # write final .env with both vars present
349
373
  (target_dir / ".env").write_text(env_text, encoding="utf-8")
350
374
 
375
+
376
+
377
+
351
378
  cfg.set_link(project_id, str(target_dir))
352
379
 
353
380
  typer.secho(f"Local folder: {target_dir}", fg=typer.colors.GREEN)
@@ -75,4 +75,8 @@ def set_env_access(access: str) -> None:
75
75
  def backend_url() -> str:
76
76
  cfg = get_config()
77
77
  url = (cfg.get("backend_url") or DEFAULTS["backend_url"]).rstrip("/")
78
+
79
+ if os.environ.get("MAIN_SEQUENCE_BACKEND_URL") is not None:
80
+ url=os.environ.get("MAIN_SEQUENCE_BACKEND_URL")
81
+
78
82
  return url
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mainsequence
3
- Version: 2.0.2
3
+ Version: 2.0.3
4
4
  Summary: Main Sequence SDK
5
5
  Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
6
  License: MainSequence GmbH SDK License Agreement
@@ -2,9 +2,9 @@ mainsequence/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  mainsequence/__main__.py,sha256=1_gCQd-MlXQxAubgVdTDgmP2117UQmj5DvTI_PASZis,162
3
3
  mainsequence/logconf.py,sha256=OLkhALon2uIDZSeGOwX3DneapkVqlwDjqJm96TRAhgA,10057
4
4
  mainsequence/cli/__init__.py,sha256=TNxXsTPgb52OhakIda9wTRh91cqoBqgQRx5TxjzQQFU,21
5
- mainsequence/cli/api.py,sha256=swUAVjJCr2xannssLcg6BrwbToPFNgqu1G0_kyVTLck,6155
6
- mainsequence/cli/cli.py,sha256=fVc5k8g96LYDrah5334vDXeSGH8_lf6unMH0WSFtG34,16435
7
- mainsequence/cli/config.py,sha256=HVTGfXaxlYE47VShvYuIo40Wdkxaf3xYM_y4FsI0mGg,2583
5
+ mainsequence/cli/api.py,sha256=PocYESdJvywSo7WyZnnJZmPR_Q8TKe-5jaNazyMhX9I,7313
6
+ mainsequence/cli/cli.py,sha256=CPG-Q_8b2KFGWGgGbfZzSx8qjauVrgBzg5UMUyQrM00,17308
7
+ mainsequence/cli/config.py,sha256=UAi0kfxro2oJhzaRdd2D3F72eGpqkYaWjSsCzBrb2LY,2705
8
8
  mainsequence/cli/ssh_utils.py,sha256=95CmZk2nIoJhNTCmifMEsE9QXJrXY3zvfxLQp3QpdiM,5088
9
9
  mainsequence/client/__init__.py,sha256=CDlJtsh0L9Z29OVMBnZsQajKBa193Yy5TkqLoilkbZM,869
10
10
  mainsequence/client/base.py,sha256=j6_iXmt6vPCS7INSOItTpM6ZbAmITAuPpMFNB9ZQTeE,15000
@@ -103,9 +103,9 @@ mainsequence/virtualfundbuilder/resource_factory/app_factory.py,sha256=XSZo9ImdT
103
103
  mainsequence/virtualfundbuilder/resource_factory/base_factory.py,sha256=jPXdK2WCaNw3r6kP3sZGIL7M4ygfIMs8ek3Yq4QYQZg,9434
104
104
  mainsequence/virtualfundbuilder/resource_factory/rebalance_factory.py,sha256=ysEeJrlbxrMPA7wFw7KDtuCTzXYkdfYZuxUFpPPY7vE,3732
105
105
  mainsequence/virtualfundbuilder/resource_factory/signal_factory.py,sha256=ywa7vxxLlQopuRwwRKyj866ftgaj8uKVoiPQ9YJ2IIo,7198
106
- mainsequence-2.0.2.dist-info/licenses/LICENSE,sha256=fXoCKgEuZXmP84_QDXpvO18QHze_6AAhd-zvZBUjJxQ,4524
107
- mainsequence-2.0.2.dist-info/METADATA,sha256=atyVDb6JvsyadKJYCHpSJ5grgkx5dhOI4SI-N7zcNc8,8028
108
- mainsequence-2.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
109
- mainsequence-2.0.2.dist-info/entry_points.txt,sha256=2J8TprrUndh7AttNTlXAaxgGtkXFUAHgXs-M7DCj5MU,58
110
- mainsequence-2.0.2.dist-info/top_level.txt,sha256=uSLD9rXMDMN0cc1x0p808bwyQMoRmYY2pdQZEWLajX8,13
111
- mainsequence-2.0.2.dist-info/RECORD,,
106
+ mainsequence-2.0.3.dist-info/licenses/LICENSE,sha256=fXoCKgEuZXmP84_QDXpvO18QHze_6AAhd-zvZBUjJxQ,4524
107
+ mainsequence-2.0.3.dist-info/METADATA,sha256=NKlRdCIFUq6JmHdtsEktvayTEKAWrhNVnWdQ4A_-JAk,8028
108
+ mainsequence-2.0.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
109
+ mainsequence-2.0.3.dist-info/entry_points.txt,sha256=2J8TprrUndh7AttNTlXAaxgGtkXFUAHgXs-M7DCj5MU,58
110
+ mainsequence-2.0.3.dist-info/top_level.txt,sha256=uSLD9rXMDMN0cc1x0p808bwyQMoRmYY2pdQZEWLajX8,13
111
+ mainsequence-2.0.3.dist-info/RECORD,,