joaovitoriasilva / endurain

My DIY fitness tracker journey. Frontend is built using Vue.js and Bootstrap CSS; Python FastAPI, Alembic, SQLAlchemy, stravalib, gpxpy, MariaDB behind the scenes. Suggestions welcome!
GNU General Public License v3.0
489 stars 12 forks source link

Issues importing from Strava #30

Open rhyst opened 1 day ago

rhyst commented 1 day ago

Firstly thanks for making endurain! Its a very nice looking project.

I was trying to import my Strava activities into Endurain and I ran into a few issues.

Descriptions

The description does not seem to be imported. I initially thought this might be due to the length of descriptions I write but it seemed to happen for descriptions of a few characters.

Whether or not that is related to the issue most of my activities have descriptions that are longer than the 2500 characters allowed by Endurain so its possible this is the reason. Is it possible to raise that limit? A brief test suggests that the Strava limit is around ~65,000 characters.

Manual Activities

I don't normally use manual activities but while attempting to confirm whether the above issue was due to the length of my descriptions I found that the import fails on "manual entry" activities with the following error:

ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/uvicorn/protocols/http/httptools_impl.py", line 399, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 70, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/fastapi/applications.py", line 1054, in __call__
    await super().__call__(scope, receive, send)
  File "/usr/local/lib/python3.12/site-packages/starlette/applications.py", line 123, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/usr/local/lib/python3.12/site-packages/starlette/middleware/errors.py", line 186, in __call__
    raise exc
  File "/usr/local/lib/python3.12/site-packages/starlette/middleware/errors.py", line 164, in __call__
    await self.app(scope, receive, _send)
  File "/usr/local/lib/python3.12/site-packages/opentelemetry/instrumentation/asgi/__init__.py", line 631, in __call__
    await self.app(scope, otel_receive, otel_send)
  File "/usr/local/lib/python3.12/site-packages/starlette/middleware/cors.py", line 93, in __call__
    await self.simple_response(scope, receive, send, request_headers=headers)
  File "/usr/local/lib/python3.12/site-packages/starlette/middleware/cors.py", line 148, in simple_response
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 65, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
    raise exc
  File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
    await app(scope, receive, sender)
  File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 756, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 776, in app
    await route.handle(scope, receive, send)
  File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 297, in handle
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 77, in app
    await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 64, in wrapped_app
    raise exc
  File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
    await app(scope, receive, sender)
  File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 75, in app
    await response(scope, receive, send)
  File "/usr/local/lib/python3.12/site-packages/starlette/responses.py", line 162, in __call__
    await self.background()
  File "/usr/local/lib/python3.12/site-packages/starlette/background.py", line 45, in __call__
    await task()
  File "/usr/local/lib/python3.12/site-packages/starlette/background.py", line 30, in __call__
    await run_in_threadpool(self.func, *self.args, **self.kwargs)
  File "/usr/local/lib/python3.12/site-packages/starlette/concurrency.py", line 42, in run_in_threadpool
    return await anyio.to_thread.run_sync(func, *args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/anyio/to_thread.py", line 56, in run_sync
    return await get_async_backend().run_sync_in_worker_thread(
File "/usr/local/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 2177, in run_sync_in_worker_thread
    return await future
           ^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 859, in run
    result = context.run(func, *args)
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/strava/activity_utils.py", line 355, in get_user_strava_activities_by_days
    num_strava_activities_processed = fetch_and_process_activities(
                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/strava/activity_utils.py", line 50, in fetch_and_process_activities
    process_activity(activity, user_id, strava_client, user_integrations, db)
  File "/app/strava/activity_utils.py", line 305, in process_activity
    parsed_activity = parse_activity(
                      ^^^^^^^^^^^^^^^
  File "/app/strava/activity_utils.py", line 106, in parse_activity
    streams = strava_client.get_activity_streams(
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/stravalib/client.py", line 1593, in get_activity_streams
    return self._get_streams(
           ^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/stravalib/client.py", line 1537, in _get_streams
    response = self.protocol.get(
               ^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/stravalib/protocol.py", line 442, in get
    return self._request(
           ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/stravalib/protocol.py", line 327, in _request
    self._handle_protocol_error(raw)
  File "/usr/local/lib/python3.12/site-packages/stravalib/protocol.py", line 368, in _handle_protocol_error
    raise exc.ObjectNotFound(msg, response=response)
stravalib.exc.ObjectNotFound: Not Found: Resource Not Found: []

Deleting / Updating

I also can't delete activities imported from Strava, nor do they update if I edit in Strava and then run the import again (both of which I would expect to work).

joaovitoriasilva commented 1 day ago

Hi, thanks for reaching out and for the feedback.

So let's break the response into several topics:

rhyst commented 1 day ago

Thank you for your swift responses!

For the manual activity it was enough to click "Add manual entry" in the top right menu, and then click "Create" at the bottom, leaving all fields as the default. I can upload an activity file if still needed though.

I also don't edit the activities very often, but it does happen occasionally.